final关键字概述

final是Java中的保留关键字,表示"最终的、不可改变的"

学习目标

理解final关键字的三种应用场景:变量、方法、类,掌握抽象类的定义和使用

final的三种用法

应用场景 作用 示例
final变量 常量,值不可修改 final int MAX_SIZE = 100;
final方法 方法不可被重写 public final void show(){}
final类 类不可被继承 public final class String{}

抽象类简介

  • 使用abstract关键字修饰的类
  • 不能直接实例化,必须被继承
  • 可以包含抽象方法(无方法体)
  • 可以有构造方法、成员变量、具体方法
  • 子类必须实现所有抽象方法

final变量详解

掌握final变量的声明、初始化及使用场景

1

final基本类型变量

一旦赋值,值不可改变

public class FinalVariablesDemo { // 1. 声明时直接初始化 final int MAX_COUNT = 100; // 2. 构造方法中初始化 final double PI; public FinalVariablesDemo() { PI = 3.1415926; // 只能赋值一次 } public void testMethod() { // 3. 局部final变量 final int localValue = 50; // localValue = 60; // 编译错误! } }
2

final引用类型变量

引用不可变,但对象内容可变

import java.util.*; public class FinalReferenceDemo { public static void main(String[] args) { // final引用变量,指向ArrayList对象 final List<String> names = new ArrayList<>(); names.add("Alice"); // 允许:修改对象内容 names.add("Bob"); // names = new ArrayList<>(); // 编译错误!引用不可变 } }
3

final静态变量

定义类常量,通常与static一起使用

public class MathConstants { // 类常量:大写+下划线命名 public static final double PI = 3.141592653589793; public static final int MAX_CONNECTIONS = 100; public static final String APP_NAME = "JavaLearning"; public static void main(String[] args) { System.out.println("圆周率:" + MathConstants.PI); } }

使用场景

  • 定义配置常量(如数据库连接参数)
  • 线程安全的共享数据
  • 方法参数防止被修改
  • 匿名内部类访问局部变量

final方法详解

防止方法被重写,保护关键算法

1

基本用法

public class Calculator { // 基本计算方法,不允许子类修改 public final double add(double a, double b) { return a + b; } public final double multiply(double a, double b) { return a * b; } // 可以重写的模板方法 public double process(double a, double b) { double result = add(a, b); return applyDiscount(result); } protected double applyDiscount(double value) { return value; // 子类可以重写这个方法 } }
2

继承中的final方法

public class AdvancedCalculator extends Calculator { // 编译错误:无法重写final方法 /* @Override public final double add(double a, double b) { return a + b + 1; // 错误! } */ // 允许:重写非final方法 @Override protected double applyDiscount(double value) { return value * 0.9; // 打9折 } }

final类详解

防止类被继承,保证类的完整性

1

final类的定义

// 定义一个不可被继承的类 public final class StringUtils { private StringUtils() {} // 防止实例化 public static boolean isEmpty(String str) { return str == null || str.trim().isEmpty(); } public static String reverse(String str) { return new StringBuilder(str).reverse().toString(); } } // 编译错误:无法继承final类 /* public class ExtendedStringUtils extends StringUtils { // 错误! } */
2

Java标准库中的final类

// Java标准库中的final类示例: public final class String { } // 字符串类 public final class Integer { } // 包装类 public final class System { } // 系统类 public final class Math { } // 数学工具类

何时使用final类

  • 工具类(如StringUtils、MathUtils)
  • 不可变对象类(如String、包装类)
  • 安全敏感的类
  • 设计为不可扩展的类

抽象类基础

理解抽象类的概念、语法和使用场景

1

抽象类的定义

// 抽象类定义 public abstract class Shape { // 成员变量 protected String color; protected boolean filled; // 构造方法 public Shape(String color, boolean filled) { this.color = color; this.filled = filled; } // 抽象方法:没有方法体 public abstract double getArea(); public abstract double getPerimeter(); // 具体方法:有实现 public String getColor() { return color; } public void setColor(String color) { this.color = color; } }
2

抽象类的特点

// 1. 不能直接实例化 // Shape shape = new Shape("red", true); // 编译错误 // 2. 可以包含抽象方法和具体方法 public abstract class Animal { private String name; public Animal(String name) { this.name = name; } // 抽象方法 public abstract void makeSound(); // 具体方法 public void sleep() { System.out.println(name + " is sleeping"); } public String getName() { return name; } }
3

继承抽象类

public class Circle extends Shape { private double radius; public Circle(String color, boolean filled, double radius) { super(color, filled); this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } @Override public double getPerimeter() { return 2 * Math.PI * radius; } }

实战案例:员工管理系统

通过完整的员工管理案例理解final和抽象类的应用

1

抽象员工类

public abstract class Employee { private final String id; // 员工ID不可变 private String name; private final LocalDate hireDate; // 入职日期不可变 public Employee(String id, String name, LocalDate hireDate) { this.id = id; this.name = name; this.hireDate = hireDate; } // 抽象方法:计算薪资 public abstract double calculateSalary(); // 抽象方法:获取职位描述 public abstract String getPosition(); // 具体方法:获取员工信息 public final String getEmployeeInfo() { return String.format("ID: %s, Name: %s, Position: %s", id, name, getPosition()); } // Getter方法 public String getId() { return id; } public String getName() { return name; } public LocalDate getHireDate() { return hireDate; } }
2

具体员工类

public class Developer extends Employee { private double baseSalary; private double bonus; public Developer(String id, String name, LocalDate hireDate, double baseSalary, double bonus) { super(id, name, hireDate); this.baseSalary = baseSalary; this.bonus = bonus; } @Override public double calculateSalary() { return baseSalary + bonus; } @Override public String getPosition() { return "Software Developer"; } } public class Manager extends Employee { private double monthlySalary; private double managementAllowance; public Manager(String id, String name, LocalDate hireDate, double monthlySalary, double allowance) { super(id, name, hireDate); this.monthlySalary = monthlySalary; this.managementAllowance = allowance; } @Override public double calculateSalary() { return monthlySalary * 12 + managementAllowance; } @Override public String getPosition() { return "Project Manager"; } }
3

测试类

import java.time.LocalDate; import java.util.*; public class EmployeeManagementSystem { public static void main(String[] args) { List<Employee> employees = new ArrayList<>(); employees.add(new Developer("DEV001", "张三", LocalDate.of(2022, 3, 15), 8000, 2000)); employees.add(new Manager("MGR001", "李四", LocalDate.of(2020, 5, 10), 12000, 5000)); double totalSalary = 0; for (Employee emp : employees) { System.out.println(emp.getEmployeeInfo()); System.out.println("月薪:" + emp.calculateSalary()); totalSalary += emp.calculateSalary(); System.out.println("---"); } System.out.println("总薪资支出:" + totalSalary); } }

常见错误与解决方案

避免final和抽象类使用中的陷阱

final变量错误

public class FinalVarErrors { final int x; // 错误:未初始化 public void method() { final int y; y = 10; // y = 20; // 错误:重复赋值 } }

解决方案:final变量必须在使用前初始化

抽象类实例化

public abstract class Animal { public abstract void makeSound(); } public class Test { public static void main(String[] args) { // Animal animal = new Animal(); // 错误:抽象类不能实例化 // 正确:使用匿名内部类 Animal dog = new Animal() { @Override public void makeSound() { System.out.println("汪汪"); } }; } }

抽象方法实现

public abstract class Vehicle { public abstract void start(); public abstract void stop(); } public class Car extends Vehicle { @Override public void start() { System.out.println("Car started"); } // 错误:未实现stop()方法 // 必须实现所有抽象方法 }

final类继承

public final class ImmutableClass { private final String value; public ImmutableClass(String value) { this.value = value; } } // 错误:不能继承final类 /* public class ExtendedImmutable extends ImmutableClass { // 编译错误 } */

综合练习

完成以下任务巩固知识:

  • 创建一个final的Config类,包含数据库连接常量
  • 设计一个抽象类Payment,包含抽象方法calculateFee()
  • 实现CreditCardPayment和PayPalPayment子类
  • 使用多态处理不同类型的支付
查看参考答案

知识总结

  • 掌握final关键字的三种用法
  • 理解抽象类的概念和语法
  • 能够正确使用抽象类和final
  • 避免常见的使用错误
  • 在实际项目中合理应用