一、抽象类(Abstract Class)
1. 基本特性
- 使用
abstract
关键字声明 - 可以包含抽象方法和具体方法
- 不能直接实例化(不能new)
- 可以包含成员变量、构造方法、普通方法
2. 语法结构
java
1 | public abstract class Animal { |
3. 使用要点
- 抽象方法:没有方法体,必须用
abstract
修饰 - 子类要求:非抽象子类必须实现所有抽象方法
- 构造方法:虽然不能实例化,但可以有构造方法供子类调用
- 访问控制:抽象方法不能用private修饰(因为需要子类实现)
4. 适用场景
- 多个相关类共享代码和关系
- 需要定义子类的共同行为规范
- 需要包含非public的成员和方法
- 需要定义非static、非final的成员变量
二、接口(Interface)
1. 基本特性
- Java 7及以前:纯抽象(只有抽象方法)
- Java 8开始:支持默认方法(default)和静态方法
- Java 9开始:支持私有方法
- 不能包含实例字段(只能是static final常量)
- 不能有构造方法
2. 语法演进
Java 7及以前
java
1 | public interface Flyable { |
Java 8+
java
1 | public interface SmartDevice { |
3. 使用要点
- 实现要求:类实现接口必须实现所有抽象方法(默认方法可选)
- 多继承:一个类可以实现多个接口
- 接口继承:接口可以继承多个其他接口
- 默认冲突:当多个接口有相同默认方法时,实现类必须重写
4. 适用场景
- 定义不相关类的共同行为
- 需要多重继承的场景
- 作为API的定义规范
- 需要定义回调函数(如EventListener)
三、抽象类与接口对比
特性 | 抽象类 | 接口 |
---|---|---|
关键字 | abstract class | interface |
方法类型 | 抽象方法+具体方法 | Java 8前只有抽象方法,之后有默认方法和静态方法 |
变量 | 可以有各种成员变量 | 只能是public static final常量 |
构造方法 | 有 | 没有 |
继承/实现 | 单继承(extends) | 多实现(implements) |
设计目的 | 代码复用和层次化设计 | 定义行为规范和能力 |
访问控制 | 可以是任意访问修饰符 | 默认public(不能是protected/private) |
多态支持 | 支持 | 支持 |
JDK版本影响 | 不受影响 | 功能随版本增强 |
四、选择原则
使用抽象类当:
- 多个相关类需要共享代码
- 需要定义非public的成员
- 需要定义非static、非final的字段
- 需要定义构造方法逻辑
使用接口当:
- 不相关的类需要实现相同的行为
- 需要多重继承
- 只关注行为规范而非实现
- 作为API定义供他人实现
组合使用:
java
1
2
3
4
5
6
7
8// 抽象类提供基础实现
abstract class Bird extends Animal implements Flyable {
// 既继承Animal的特性,又实现Flyable的能力
@Override
public void fly() {
System.out.println("用翅膀飞行");
}
}
五、最新发展(Java 8-17)
- 接口的增强:
- 默认方法(解决接口演化问题)
- 静态方法(工具方法)
- 私有方法(Java 9,代码复用)
- 接口与抽象类的界限模糊:
- 接口现在也可以有方法实现
- 但接口仍然不能有实例状态(成员变量)
- record类与sealed类:
- Java 14引入record(数据载体)
- Java 15引入sealed类(受限继承)
- 这些新特性与抽象类/接口形成互补
六、设计模式中的应用
模板方法模式(抽象类典型应用):
java
1
2
3
4
5
6
7
8
9
10
11abstract class Game {
abstract void initialize();
abstract void startPlay();
// 模板方法
public final void play() {
initialize();
startPlay();
endPlay();
}
}策略模式(接口典型应用):
java
1
2
3
4
5
6
7interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) { /*...*/ }
}适配器模式(结合使用):
java
1
2
3
4
5
6
7interface Target {
void request();
}
abstract class Adapter implements Target {
public void request() { /* 默认实现 */ }
}
掌握抽象类和接口的区别与适用场景,是Java面向对象设计的重要基础。随着Java版本的更新,两者的功能都在不断增强,但核心设计理念保持不变:抽象类侧重于”是什么”,接口侧重于”能做什么”。