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,却能带成员变量、构造方法和具体逻辑,是与普通类互补、承上启下的设计角色。