选抽象类还是接口取决于需求:需代码复用、状态初始化或访问控制时用抽象类;需行为约定、多能力组合或结构约束时用接口。

选抽象类还是接口,关键看你要解决的是“代码复用”还是“行为约定”。两者都能支撑继承和多态,但机制和适用场景不同。
什么时候该用抽象类
当你需要共享实现逻辑、初始化状态或控制访问权限时,抽象类更合适。
- 可以包含具体方法(比如通用的日志记录、数据校验),子类直接复用,不用重复写
- 支持构造函数,能在实例化时初始化 shared state(比如数据库连接配置、默认超时时间)
- 允许 protected 或 private 成员,保护内部逻辑不被外部或无关子类访问
- 适合表达 “is-a” 关系:比如
Animal是基类,Dog和Cat是它的具体种类
什么时候该用接口
当你关注对象“能做什么”,而不是“它是什么”,尤其需要灵活组合能力时,接口是首选。
- 定义纯契约:只声明方法签名和只读属性,强制实现类提供自己的逻辑(比如
Alarm、Drawable、Serializable) - 一个类可同时实现多个接口(
class Car implements Alarm, Drawable, Serializable),突破单继承限制 - 所有成员默认 public,不可设 private 或 protected,天然适合解耦和类型描述
- 常用于类型标注:比如
let user: UserShape,不涉及行为实现,只约束结构
继承与多态的实际表现
两者都支持多态,但路径不同:
- 抽象类的多态靠 继承 + 重写抽象方法:父类声明
abstract speak(): void,子类各自实现,调用时根据实际类型执行对应版本 - 接口的多态靠 实现 + 类型兼容:多个类实现同一接口,变量声明为接口类型,运行时自动调用对应实现(
let device: Alarm = new Car(); device.alert()) - 抽象类只能单继承(
extends一次),但可以同时implements多个接口 - 接口可继承其他接口(
interface A extends B, C),形成能力叠加,但不能继承抽象类
一个实用判断流程
写代码前快速自问三个问题:
- 是否需要在基类里写可复用的方法体?→ 是 → 选抽象类
- 是否要让一个类具备多种独立能力(报警+可绘制+可导出)?→ 是 → 必须用接口
- 是否要约束对象结构(比如 API 返回数据形状)而不关心行为?→ 是 → 接口更轻量、更直观


















