Java 抽象类

抽象类(abstract class)是 Java 中用来"定规则、做模板"的类:把必须由子类完成的方法声明为抽象方法,只给签名不给实现。它是面向对象抽象能力的中坚,理解它才能设计出既约束统一、又允许差异的类体系。

抽象方法与抽象类

用 abstract 修饰的方法叫抽象方法:只有方法声明、没有方法体(没有 {})。含有抽象方法的类必须声明成 abstract 类:

abstract class Animal {
    abstract void speak();      // 抽象方法:只声明,不实现
}
  • 抽象方法以分号结尾,不能写方法体。
  • 非抽象子类必须实现父类的所有抽象方法,否则子类也得声明为 abstract。
  • abstract 不能与 final 同时使用:final 禁止继承,abstract 却要求子类实现。

为什么用抽象类

抽象类解决"父类方法没法写、又必须约束子类"的问题:把公共逻辑放进父类的具体方法,把变化的步骤留成抽象方法,让每个子类去填空,这就是模板方法思想。例如图形面积,不同图形算法不同,父类只定规则:

abstract class Shape {
    String name;                              // 可以有成员变量
    Shape(String name) { this.name = name; }  // 可以有构造方法
    abstract double area();                   // 抽象方法:子类各自实现
    void show() {                             // 具体方法:固定流程
        System.out.println(name + " 面积 = " + area());
    }
}

抽象类不能实例化

抽象类可能含有未实现的方法,因此不能用 new 创建。但它可以被继承,父类引用可以指向子类对象:

// Shape s = new Shape("圆");   // 编译错误:抽象类不能实例化
class Circle extends Shape {
    double r;
    Circle(double r) { super("圆"); this.r = r; }
    @Override double area() { return 3.14 * r * r; }
}

// —— 片段需放进 main 方法中运行 ——
Shape s = new Circle(2);
s.show();                       // 运行时调用子类的 area()
// 输出:圆 面积 = 12.56

与普通类的区别

  • 普通类可以实例化,抽象类不能。
  • 普通类不能有抽象方法,抽象类可以有(也可以没有)。
  • 抽象类更强调"约束 + 复用":公共代码放父类,子类只实现差异部分。

示例:动物叫声

一个完整的抽象类应用:greet() 固定"先报名字再叫"的流程,叫声留给子类:

abstract class Animal {
    String name;
    Animal(String name) { this.name = name; }
    abstract void speak();                  // 规则:必须实现
    void greet() {                          // 模板方法
        System.out.print(name + ":");
        speak();
    }
}
class Dog extends Animal {
    Dog() { super("狗"); }
    @Override void speak() { System.out.println("汪汪"); }
}
class Cat extends Animal {
    Cat() { super("猫"); }
    @Override void speak() { System.out.println("喵喵"); }
}

// —— 片段需放进 main 方法中运行 ——
Animal[] as = { new Dog(), new Cat() };
for (Animal a : as) a.greet();
// 输出:狗:汪汪
// 输出:猫:喵喵

抽象类是"模板":把共同流程写成具体方法,把差异点留成抽象方法约束子类实现。它不能 new,却能带成员变量、构造方法和具体逻辑,是与普通类互补、承上启下的设计角色。

笔记加载中…