第32章

Java抽象类和抽象方法

深入学习abstract关键字的使用,掌握抽象类和抽象方法的定义、继承和实现

学习目标

抽象类基础概念

什么是抽象类?

抽象类是使用abstract关键字修饰的类,它不能被直接实例化。抽象类通常用于定义一组相关类的通用特征和行为,同时强制子类实现特定的方法。

抽象类的特点

  • 不能实例化:不能使用new关键字创建抽象类的对象
  • 可以有构造方法:用于初始化抽象类中的成员变量
  • 可以包含具体方法:提供通用的实现逻辑
  • 可以包含抽象方法:强制子类提供具体实现
  • 可以有成员变量:存储对象的状态信息

抽象方法

抽象方法是只有声明没有实现的方法,使用abstract关键字修饰。抽象方法只能存在于抽象类中,子类必须重写所有的抽象方法。

// 抽象类示例
abstract class Animal {
    protected String name;
    
    // 构造方法
    public Animal(String name) {
        this.name = name;
    }
    
    // 具体方法
    public void sleep() {
        System.out.println(name + "正在睡觉...");
    }
    
    // 抽象方法
    public abstract void makeSound();
    public abstract void move();
}

动物抽象类示例

通过动物类的例子来理解抽象类的基本用法。Animal抽象类定义了所有动物的通用特征,而具体的动物类实现各自特有的行为。

// 具体类:狗
class Dog extends Animal {
    private String breed;
    
    public Dog(String name, String breed) {
        super(name);
        this.breed = breed;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + "汪汪叫!");
    }
    
    @Override
    public void move() {
        System.out.println(name + "在地上跑来跑去");
    }
    
    // 狗特有的方法
    public void wagTail() {
        System.out.println(name + "摇尾巴表示友好");
    }
}
💻 查看完整代码 - 在线IDE体验

几何图形抽象类示例

通过几何图形的例子展示抽象类在数学计算中的应用。Shape抽象类定义了图形的通用特征,不同的图形类实现具体的计算方法。

abstract class Shape {
    protected String color;
    protected String name;
    
    public Shape(String name, String color) {
        this.name = name;
        this.color = color;
    }
    
    // 抽象方法:计算面积
    public abstract double calculateArea();
    
    // 抽象方法:计算周长
    public abstract double calculatePerimeter();
    
    // 具体方法:显示图形信息
    public void displayInfo() {
        System.out.println("图形: " + name);
        System.out.println("颜色: " + color);
        System.out.println("面积: " + String.format("%.2f", calculateArea()));
        System.out.println("周长: " + String.format("%.2f", calculatePerimeter()));
    }
}

抽象类设计原则

设计指导原则

何时使用抽象类

  • 多个相关类需要共享代码时
  • 需要提供部分实现,部分留给子类时
  • 需要强制子类实现某些方法时
  • 定义算法骨架,具体步骤由子类实现
  • 需要在类中定义实例变量时

设计误区

  • 过度抽象,为了抽象而抽象
  • 抽象类的职责不清晰
  • 继承层次过深,难以维护
  • 与接口的使用场景混淆
  • 抽象方法设计不合理

抽象类 vs 接口

理解抽象类和接口的区别,有助于在实际开发中做出正确的设计选择。

特性 抽象类 接口
关键字 abstract class interface
继承 单继承 多实现
方法 可以有具体方法 默认抽象方法(Java 8+可有默认方法)
变量 可以有实例变量 只能有常量
构造方法 可以有 不能有
访问修饰符 任意 public

实际应用场景

常见应用场景

  • 框架设计:定义框架的骨架结构,如Spring框架中的抽象类
  • 模板方法模式:定义算法模板,具体步骤由子类实现
  • 工厂模式:抽象工厂类定义创建对象的接口
  • 数据访问层:抽象DAO类提供通用的数据库操作
  • 业务逻辑层:抽象服务类定义业务处理流程

最佳实践建议

设计建议

  • 合理命名:使用清晰的类名表达抽象概念
  • 文档注释:为抽象方法提供详细的文档说明
  • 构造方法:提供合适的构造方法初始化通用属性
  • 访问修饰符:合理使用protected让子类访问
  • 方法设计:抽象方法应该有明确的职责和契约
  • 单一职责:每个抽象类应该有明确单一的职责

本章小结