抽象类用于表达“是什么”,支持单继承,可包含构造方法、成员变量和具体方法,适合共享状态与行为;接口定义“能做什么”,支持多实现,JDK 8 后可有 default 和 static 方法,但无构造器和实例字段,强调行为契约。选抽象类建模类本质,选接口建模对象能力。

抽象类和接口的核心区别在于设计意图和语法能力:抽象类用于表达“是什么”,强调类的继承关系和共性代码复用;接口用于定义“能做什么”,强调行为契约和多维度能力组合。
语法限制不同
抽象类可以有构造方法、普通成员变量、静态方法、具体方法(含实现)、protected 和 private 成员;接口在 JDK 8 之前只能有 public static final 字段和 public abstract 方法,JDK 8 后可定义 default 方法和 static 方法,但不能有构造器、实例字段或非 public 成员。
- 抽象类支持单继承,一个类只能 extends 一个抽象类
- 接口支持多实现,一个类可 implements 多个接口
- 接口中的所有方法默认是 public 的,不能声明为 private 或 protected
- 抽象类中可以有 main 方法并直接运行;接口不能直接运行(无静态块或 main 的执行入口)
设计目的与使用场景不同
抽象类适合描述具有共同状态和行为的一组类,比如“动物”抽象类可包含 name、age 字段和 breathe() 方法;接口适合定义能力契约,比如 Flyable、Swimmable、Runnable,让鸟、飞机、鸭子等不相关的类型都能实现同一行为。
- 当需要共享代码逻辑或维护状态时,优先选抽象类
- 当需要解耦行为定义与具体实现,或需让不相关的类具备相同能力时,优先选接口
- 从 JDK 8 开始,default 方法让接口也能提供默认行为,但仅限于“能力增强”,不宜替代抽象类做核心建模
演变趋势:接口越来越“强”,但角色未变
JDK 8 引入 default 和 static 方法,JDK 9 支持 private 方法(用于 default 方法间复用),让接口更灵活。但这不是为了取代抽象类,而是弥补接口过去无法提供默认实现的短板,使其更适合定义“契约+轻量默认行为”的场景。
立即学习“Java免费学习笔记(深入)”;
- default 方法不能访问 this 的实例状态(没有 this 指向抽象类那种对象上下文)
- 接口仍不能有实例变量,因此无法封装可变状态
- 如果多个接口提供了同名 default 方法,实现类必须重写该方法,否则编译报错
基本上就这些。选抽象类还是接口,关键看你在建模“类的本质”还是“对象的能力”。不复杂但容易忽略的是:别为了省几行代码而滥用 default 方法——该由父类承担的共性逻辑,依然该放在抽象类里。











