抽象类强调“是什么”,用于定义类族共性模板并支持状态与初始化;接口强调“能做什么”,用于跨类型行为契约和多能力组合。选型依据:需共享状态或构造逻辑用抽象类,需多实现或松耦合用接口。

Java 抽象类与接口的对比,核心不在语法罗列,而在设计意图和实际约束。面试官真正想听的是:你能不能根据场景做合理取舍,而不是背出“接口不能有构造器”这种孤立结论。
看设计目的:契约 vs 模板
接口回答的是“这个对象能做什么”,比如 Flyable、Serializable、Comparable——它们不关心你是鸟、飞机还是无人机,只约定你得提供 fly() 或 compareTo() 这个能力。抽象类回答的是“这个对象是什么”,比如 Animal、Shape、Vehicle——它天然带有身份属性(共有的字段、初始化逻辑、基础行为),子类是它的具体化身。
- 选接口:当多个不相关的类需要统一对外暴露相同能力(如日志组件既要支持文件输出,也要支持网络发送,二者无继承关系)
- 选抽象类:当一组类天然属于同一族,且共享状态或通用流程(如所有
PaymentProcessor都要校验金额、记录流水号、统一异常包装)
看继承结构:多实现 vs 单继承
Java 不允许类多重继承,但允许一个类同时 implements 多个接口。这意味着你能轻松组合能力:class Drone extends Aircraft implements Flyable, CameraOperable, RemoteControllable。而抽象类只能 extends 一个——如果你已经继承了 SmartDevice,就无法再继承 FlightController。
- 需要叠加多种角色?必须用接口
- 已有父类但还想复用另一套逻辑?把那套逻辑抽成接口,而非抽象类
- 框架设计中常让核心基类为抽象类,周边扩展能力全走接口(如 Spring 的
InitializingBean、DisposableBean)
看成员能力:状态与初始化
抽象类可以有构造方法、protected 字段、普通方法、静态方法、甚至 private 工具方法;接口只能有 public static final 常量和 public 方法(默认、静态、抽象),且不能有构造器。
立即学习“Java免费学习笔记(深入)”;
- 需要在创建子类时强制传入某个配置(如数据库连接池名、线程数)?抽象类的构造器能自然承载
- 需要子类共享一个可变状态(如缓存容器、计数器)?只能放抽象类里,接口做不到
- 只是定义几个固定常量(如 HTTP 状态码、协议版本)?放接口里更清晰,也避免子类意外修改
看演进兼容性:default 方法不是万能补丁
JDK 8 引入 default 方法,常被误读为“接口也能写实现”。但它本质是向后兼容机制:当你给已有接口新增方法时,不用强制所有实现类立刻改代码。它不适合放核心逻辑。
-
default方法适合通用辅助行为(如集合接口的stream()、forEach()) - 若 default 方法开始调用其他 default 方法、依赖子类字段、或变得复杂——说明它本该属于抽象类
- 抽象类中的具体方法可被
final修饰锁定,接口无法做到这点


















