在 Java 中,抽象类(Abstract Class)是一种被 abstract 关键字修饰的特殊类,它不能被直接实例化,主要用于封装子类的通用属性和方法,并通过抽象方法强制子类实现特定行为。以下是抽象类的定义和使用详解:

一、抽象类的定义

使用 abstract 关键字声明抽象类,语法如下:

[修饰符] abstract class 类名 [extends 父类] {
    // 1. 成员变量(普通类的变量,可被继承)
    数据类型 变量名;

    // 2. 构造方法(供子类继承时调用,不能直接用于实例化)
    类名(参数列表) {
        // 初始化逻辑
    }

    // 3. 普通方法(有具体实现,子类可直接使用或重写)
    返回值类型 方法名(参数列表) {
        // 方法体
    }

    // 4. 抽象方法(无实现,用 abstract 修饰,子类必须重写)
    abstract 返回值类型 抽象方法名(参数列表);
}

核心规则

  • 抽象类不能被实例化(无法用 new 创建对象)。
  • 包含抽象方法的类必须声明为抽象类;但抽象类可以不包含抽象方法(仅作为 “不能实例化的类”)。
  • 子类继承抽象类时,必须重写所有抽象方法(除非子类也是抽象类)。

二、抽象类的使用(继承与实现)

子类通过 extends 关键字继承抽象类,并强制实现所有抽象方法(非抽象子类)。以下通过 “交通工具” 场景示例说明:

1. 定义抽象类(通用模板)
// 抽象类:交通工具(封装通用属性和方法)
abstract class Vehicle {
    // 成员变量:所有交通工具共有的属性
    protected String brand; // 品牌
    protected int speed;    // 速度

    // 构造方法:初始化通用属性
    public Vehicle(String brand, int speed) {
        this.brand = brand;
        this.speed = speed;
    }

    // 普通方法:有具体实现(所有交通工具通用的功能)
    public void start() {
        System.out.println(brand + "启动了");
    }

    public void stop() {
        System.out.println(brand + "停止了");
    }

    // 抽象方法:无实现(不同交通工具的特有行为,强制子类实现)
    public abstract void run(); // 行驶方式
    public abstract void fuelType(); // 燃料类型
}
2. 子类继承并实现抽象方法
// 子类1:汽车(继承抽象类,必须实现所有抽象方法)
class Car extends Vehicle {
    // 调用父类构造方法
    public Car(String brand, int speed) {
        super(brand, speed);
    }

    // 实现抽象方法:行驶方式
    @Override
    public void run() {
        System.out.println(brand + "以" + speed + "km/h在公路上行驶");
    }

    // 实现抽象方法:燃料类型
    @Override
    public void fuelType() {
        System.out.println(brand + "使用汽油作为燃料");
    }

    // 可选:重写父类的普通方法
    @Override
    public void start() {
        System.out.println(brand + "(汽车)一键启动");
    }
}

// 子类2:自行车(继承抽象类)
class Bicycle extends Vehicle {
    public Bicycle(String brand, int speed) {
        super(brand, speed);
    }

    @Override
    public void run() {
        System.out.println(brand + "以" + speed + "km/h在自行车道行驶");
    }

    @Override
    public void fuelType() {
        System.out.println(brand + "不需要燃料,靠人力驱动");
    }
}
3. 测试抽象类的使用
public class AbstractDemo {
    public static void main(String[] args) {
        // 抽象类不能实例化(报错):Vehicle v = new Vehicle("未知", 0);

        // 多态:抽象类引用指向子类对象
        Vehicle car = new Car("特斯拉", 120);
        Vehicle bike = new Bicycle("捷安特", 15);

        // 调用方法(子类实现的抽象方法和父类的普通方法)
        car.start();       // 输出:特斯拉(汽车)一键启动(重写的普通方法)
        car.run();         // 输出:特斯拉以120km/h在公路上行驶(实现的抽象方法)
        car.fuelType();    // 输出:特斯拉使用汽油作为燃料(实现的抽象方法)
        car.stop();        // 输出:特斯拉停止了(父类的普通方法)

        System.out.println("---");

        bike.start();      // 输出:捷安特启动了(父类的普通方法)
        bike.run();        // 输出:捷安特以15km/h在自行车道行驶
        bike.fuelType();   // 输出:捷安特不需要燃料,靠人力驱动
        bike.stop();       // 输出:捷安特停止了
    }
}

三、抽象类的核心作用

  1. 代码复用:将子类的通用逻辑(如 start()stop())放在抽象类中,避免重复开发。
  2. 规范行为:通过抽象方法(如 run()fuelType())强制子类实现特定功能,确保子类行为的一致性。
  3. 多态支持:抽象类引用可以指向任意子类对象,实现 “同一接口,不同实现” 的灵活调用(如示例中用 Vehicle 引用统一操作 Car 和 Bicycle)。

四、抽象类与接口的区别

特性抽象类(Abstract Class)接口(Interface)
关键字abstract classinterface
继承方式子类用 extends 单继承类用 implements 多实现
方法实现可包含普通方法(有实现)和抽象方法JDK8+ 可包含抽象方法、默认方法、静态方法
成员变量可包含任意变量(非静态 / 非 final)变量默认是 public static final(常量)
构造方法有构造方法(供子类调用)无构造方法
设计意图表示 “is-a” 关系(强调继承和复用)表示 “has-a” 能力(强调规范和多实现)
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐