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
- 避免常见的使用错误
- 在实际项目中合理应用