选抽象类还是接口取决于语义与设计目标:抽象类表达“它是什么”,适合is-a关系、代码复用和构造器初始化;接口表达“它能做什么”,支持多重能力、行为契约与解耦;二者常协同使用,接口定义能力契约,抽象类提供实现骨架。

选抽象类还是接口,关键看你想表达“它是什么”,还是“它能做什么”。
想复用代码、建层级结构,用抽象类
抽象类适合有共同属性和基础逻辑的一组类。比如多个动物类都带 name、age 字段,都有通用的呼吸、进食流程,只是叫声不同——这些共性可以直接写在抽象类里,子类只管重写抽象方法。
- 需要构造器初始化公共字段时,只能用抽象类(接口不能有构造方法)
- 子类之间存在明显的 is-a 关系,比如 Dog 是 Animal 的一种,适合继承抽象类
- 想提供部分默认实现(比如模板方法模式中固定流程+可变步骤),抽象类更自然
想定义行为契约、支持多重能力,用接口
接口不关心对象“是谁”,只规定“能干什么”。一个类可以同时是可序列化的、可比较的、可克隆的——这些能力彼此无关,但都可以通过实现不同接口来叠加。
- 需要让不相关的类遵守同一套行为规范(比如 Payment、Notification、Logger 都要支持 retry())
- 要求一个类具备多种角色(如 Robot 既要 move() 又要 speak() 还要 charge()),就实现多个接口
- 希望解耦调用方与具体实现(比如 Service 层只依赖 UserService 接口,不关心是 MySQLUserServiceImpl 还是 MockUserServiceImpl)
现实项目里,两者经常一起用
不是非此即彼。典型做法是:用接口定义顶层能力(如 Drawable、Calculable),再用抽象类为某类实现提供骨架(如 AbstractShape 含 color、borderWidth 和默认 drawOutline() 方法)。这样既保留扩展性,又减少重复编码。
立即学习“Java免费学习笔记(深入)”;
- 接口负责“对外承诺”,抽象类负责“对内支撑”
- Java 8+ 接口支持 default 方法,但别把它当抽象类用——default 方法应是真正通用的、极少被重写的辅助逻辑
- 如果发现抽象类里全是抽象方法,没有字段也没有具体实现,那它大概率该改成接口


















