接口是“行为契约”,抽象类是“共性模板”;接口定义“能做什么”,抽象类明确“是什么、怎么起步”。

直接说核心:接口是“行为契约”,抽象类是“共性模板”。一个讲“能做什么”,一个讲“是什么、怎么起步”。
设计目的不同:规范 vs 共性
接口定义一类动作的统一入口,比如ILoggable只管“能不能记录日志”,不管谁记、在哪记;抽象类则提供可复用的基础结构,比如DatabaseConnection抽象类可以封装连接池管理、重试逻辑,子类只需填空式实现open()和close()。
- 选接口:当多个不相关的类(如User、Order、Payment)都需要支持同一行为(如validate())
- 选抽象类:当一组类天然属于同一体系(如Circle、Rectangle都是Shape),且有共享字段(如color)、初始化逻辑或默认方法(如drawOutline())
语法与成员限制不同
接口成员默认公开、无状态、无构造器;抽象类更像“半成品类”,权限自由、可持状态、能初始化。
- 接口不能有构造方法,也不能定义普通字段——所有变量自动是public static final常量
- 抽象类可以有protected字段、private辅助方法、带参数的构造器(供子类super()调用)
- Java 8+ 接口支持default和static方法,但它们不能访问实例状态,也不改变“接口不持状态”的本质
继承规则与扩展影响
一个类只能extends一个抽象类,但可以implements多个接口;这个差异直接影响系统演进方式。
- 加新功能时:新增接口方法,所有实现类必须响应(除非用default方法兜底);在抽象类里加一个protected工具方法,子类完全无感
- 组合能力上:FileInputStream既继承InputStream(抽象类),又实现AutoCloseable和Closeable(接口),体现“单基类 + 多能力”的典型分层
怎么选?看三个关键问题
写代码前快速自问:
- 要不要共享字段或非静态状态?→ 要就用抽象类
- 有没有构造逻辑需要子类参与(如校验参数、初始化资源)?→ 有就用抽象类
- 这个“抽象”是给一类东西贴标签(如Runnable、Serializable),还是为子类搭脚手架?→ 前者接口,后者抽象类

















