在 Java 中,abstract 是一个关键字,用于修饰类或方法,表示“抽象的”。它主要用于定义抽象类和抽象方法,是面向对象编程中实现抽象和多态的重要机制。
一、抽象类(Abstract Class)
抽象类是用 abstract 关键字修饰的类。它不能被直接实例化,只能被其他类继承。抽象类通常作为父类,定义子类共有的属性和行为,并可以包含抽象方法。
特点:
不能实例化:抽象类不能使用 new 关键字创建对象。
可以包含抽象方法和非抽象方法:抽象方法没有方法体,必须由子类实现;非抽象方法可以有具体实现。
可以包含构造器:虽然不能实例化,但抽象类可以有构造器,供子类调用。
子类必须实现抽象方法:如果一个子类继承了抽象类,而没有实现所有抽象方法,则该子类也必须声明为抽象类。
示例:
abstract class Animal {
public abstract void makeSound(); // 抽象方法
public void sleep() { // 普通方法
System.out.println("Animal is sleeping");
}
}
class Dog extends Animal {
public void makeSound() {
System.out.println("Dog barks");
}
}
二、抽象方法(Abstract Method)
抽象方法是用 abstract 关键字修饰的方法,它没有方法体,仅声明方法签名。抽象方法必须在抽象类中定义,子类必须实现这些方法。
特点:
没有方法体:抽象方法以分号结尾,不包含实现代码。
必须在抽象类中定义:不能在普通类中定义抽象方法。
不能使用 private、static、final 修饰:因为这些修饰符与抽象方法的重写机制冲突。
子类必须实现:如果子类不实现抽象方法,则该子类也必须声明为抽象类。
示例:
abstract class Shape {
public abstract double area(); // 抽象方法
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double area() {
return Math.PI * radius * radius;
}
}
三、抽象类与接口的区别
| 特性 | 抽象类(Abstract Class) | 接口(Interface) |
| 继承 | 单继承(一个类只能继承一个抽象类) | 多实现(一个类可以实现多个接口) |
| 方法 | 可包含抽象方法和具体方法 | Java 8 前只能有抽象方法,之后可包含默认方法和静态方法 |
| 字段 | 可包含任意类型的字段(普通、静态、常量) | 只能包含 public static final 常量 |
| 构造器 | 有构造器 | 无构造器 |
| 设计目的 | 表示“是一个”关系(is-a) | 表示“具有一种能力”(can-do) |
四、使用场景
抽象类适用于以下情况:
- 需要定义一组相关类的模板。
- 共享代码,同时保留部分方法由子类实现。
- 定义一个通用类结构,强制子类实现某些行为。
总结
abstract 关键字在 Java 中用于定义抽象类和抽象方法,其核心目的是定义规范、隐藏实现、支持多态。抽象类不能被实例化,必须由子类继承并实现其中的抽象方法。通过这种方式,Java 实现了代码的复用性和灵活性,是面向对象编程的重要组成部分。