接口定义能力契约,抽象类提供结构模板:接口规范跨域行为(如loggable)、支持多实现;抽象类封装同源类共性(如reportgenerator)、含状态与具体方法;二者协同构建清晰架构。

接口与抽象类在架构中划分职责,核心在于区分“能力契约”和“结构模板”——前者管对外承诺,后者管内部复用。
接口负责定义跨域行为契约
当多个不相关的类需要统一对外提供某种能力时,用接口。它不关心实现者是谁、从哪来,只规定“必须能做什么”。
- 适合场景:日志记录(Loggable)、序列化(Serializable)、回调通知(OnCompleteListener)等跨模块、跨团队的协作约定
- 一个类可实现多个接口,天然支持能力组合,比如 UserService implements Authenticatable, Auditable, Exportable
- 接口方法默认 public,字段只能是 public static final 常量,不维护状态,利于解耦和替换
抽象类负责封装同源类的共性结构
当一组类天然属于同一类事物,且共享字段、初始化逻辑或部分实现时,用抽象类。它表达的是“是什么”,并提供可复用的骨架。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 适合场景:报表生成器(ReportGenerator)、消息发送器(MessageSender)、游戏角色(GameCharacter)等有明确继承关系的模块
- 可含 protected 字段、构造方法、具体方法(如通用校验、资源清理),子类通过 super() 初始化、直接复用
- 强制单继承,确保层级清晰;抽象方法则把变化点留给子类,比如 formatData() 由 PDF/Excel/CsvReport 各自实现
混合使用是常见架构实践
真实系统中,二者常协同工作:抽象类实现核心流程,接口暴露扩展点。
- 例如订单服务:抽象类 AbstractOrderProcessor 封装校验、扣减库存、更新状态等固定流程;同时实现 Compensable 接口支持事务回滚,实现 Observable 接口支持事件监听
- 框架设计中,Spring 的 AbstractController 是抽象类,而 InitializingBean、DisposableBean 是接口——结构归结构,生命周期契约归契约
- 避免把本该是接口的能力塞进抽象类,否则会绑架所有子类;也别把本该复用的状态逻辑拆到接口里,因为接口不能存实例变量
关键不是语法能不能写,而是这个东西在系统里“代表什么”:如果是身份归属和可复用结构,交给抽象类;如果是能力承诺和协作边界,交给接口。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










