接口定义“能做什么”,抽象类定义“是什么并部分怎么做”;接口是行为契约,无状态、多实现;抽象类是类骨架,可含状态与部分实现、单继承;二者互补,常组合使用。

接口和抽象类都用于约束子类行为、提升代码复用与可维护性,但设计意图和使用场景完全不同。简单说:接口定义“能做什么”,抽象类定义“是什么并部分怎么做”。
核心定位不同
接口是一份契约,只声明方法签名(名称、参数、返回值),不提供任何实现,也不允许保存状态。它回答的是“这个类必须支持哪些操作”。比如 Logger 接口强制所有日志类都有 log() 方法,但不管你是写到文件、输出到控制台还是发到远程服务。
抽象类是一个不完整的类骨架,可以包含抽象方法(无实现)、具体方法(有逻辑)甚至属性和构造函数。它回答的是“这类对象的基本结构和共性行为是什么”。比如 DatabaseConnection 抽象类可封装连接池、重试机制等通用逻辑,同时要求子类实现 connect() 和 disconnect() 这样的差异化步骤。
语法与限制差异明显
- 接口用 interface 声明,类用 implements 实现;抽象类用 abstract class 声明,类用 extends 继承
- 接口中所有方法自动为 public,不能用 private 或 protected;抽象类的方法可自由指定访问控制
- 接口不能定义属性(除常量外),不能有构造函数;抽象类可以有属性、构造函数、静态成员
- 一个类可 implements 多个接口,但只能 extends 一个抽象类
实际选型建议
优先用接口的情况:
- 需要统一多个无关类的行为(如 Cacheable、Renderable)
- 希望支持灵活替换(换数据库驱动、换支付网关,只需新实现同一接口)
- 构建松耦合系统,让函数只依赖接口类型而非具体类
优先用抽象类的情况:
- 存在大量共用逻辑,且这些逻辑天然属于某类继承体系(如所有控制器共享中间件执行流程)
- 需要初始化资源或管理状态(如抽象基类中定义连接句柄、配置对象)
- 想强制子类遵循某种结构(既有必须重写的抽象方法,也有可直接复用的具体方法)
它们不是互斥的,而是互补的
常见模式是组合使用:抽象类实现一个或多个接口。例如,AbstractFileLogger 可以 implements Logger 并 extends AbstractLogger,既满足日志契约,又复用格式化、时间戳等公共能力。这样既保持规范统一,又避免重复编码。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











