接口定义“能做什么”,强调行为契约;抽象类定义“是什么”,强调类型共性。接口无状态、多实现;抽象类可含状态与构造器、单继承。优先接口用于跨类型行为与解耦,优先抽象类用于共享逻辑与状态约束。

接口和抽象类在 Java 中都用于抽象建模,但设计意图、语法能力与使用场景有本质差异。选错会影响扩展性、复用性和团队协作效率。
核心定位不同:契约 vs 模板
接口定义“能做什么”,强调行为契约(like-a关系),比如 Flyable、Serializable;它不关心实现者是谁,只要求具备该能力。抽象类定义“是什么”,强调类型共性(is-a关系),比如 Animal、InputStream;它提供基础结构,子类天然继承其身份与部分实现。
成员能力差异明显
抽象类更“像类”:可含构造器、普通字段(实例变量)、私有方法、静态块、初始化块、protected 方法等;支持完整的访问控制。接口更“像协议”:所有字段自动是 public static final 常量;所有普通方法默认 public abstract;JDK 8+ 允许 default(实例方法)和 static(工具方法),但不能有实例状态或构造逻辑。
继承机制决定组合方式
- 一个类只能 extends 一个抽象类(单继承)
- 一个类可以 implements 多个接口(多实现)
- 抽象类本身可 implements 接口,也可 extends 另一个抽象类
- 接口可 extends 多个其他接口,形成能力叠加
实际选型建议
优先用接口当系统需要:
立即学习“Java免费学习笔记(深入)”;
- 跨类型统一行为(如
Comparable被 String、Date、自定义类共同实现) - 解耦模块(如 DAO 层定义
UserRepository接口,内存/MySQL/Redis 实现各自版本) - 后续可能追加新能力(借助 default 方法向后兼容)
优先用抽象类当系统需要:
- 共享代码逻辑(如模板方法模式中,
AbstractList封装了size()、isEmpty()等通用实现) - 强制子类携带某些状态(如抽象类中定义
protected String id;) - 需控制初始化流程(通过抽象类构造器约束子类创建时的参数校验或资源准备)
两者不互斥——常见做法是抽象类实现核心接口,既保证行为契约,又提供可复用骨架。










