接口代表“能做什么”,命名用uppercamelcase且具能力性(如userservice);抽象类表达“是什么”和共有骨架,命名须以abstract/base开头(如abstractorderprocessor);二者需分包管理,接口放api(contract),抽象类放support(template)。

接口与抽象类的使用方式,直接影响团队代码的可读性、可维护性和扩展一致性。统一标准不是为了约束,而是为了让不同人写的代码“看起来像一个人写的”,尤其在多人协作或跨模块调用时,能快速理解意图、安全替换实现、避免隐性陷阱。
接口命名与定义规范
接口是契约,代表“能做什么”,命名要体现能力而非实现。必须用 UpperCamelCase,且优先使用动词性或角色性名词,避免泛泛的 I 开头(如 IUserService 已过时)。
- 推荐:UserService、OrderRepository、PaymentCallbackHandler
- 不推荐:IUserService、BaseService、MyInterface
- 接口方法名统一用 lowerCamelCase,语义明确,如 sendEmail()、findById()、isExpired()
- 禁止在接口中定义非 public 的方法(Java 8+ 默认方法除外),所有方法默认 public,无需显式声明
抽象类命名与设计边界
抽象类表达“是什么”和“共有的骨架”,命名必须以 Abstract 或 Base 开头,明确提示继承者需补全逻辑。它不是用来替代接口的,而是当多个实现共享状态、模板流程或通用工具方法时才引入。
- 推荐:AbstractOrderProcessor、BaseDataSyncTask、AbstractNotificationSender
- 不推荐:OrderProcessor(无 Abstract 前缀易被误当成具体类)、CommonService
- 抽象类中可含 protected 工具方法、final 模板方法、default 实现,但避免 public 具体实现——那是具体子类的责任
- 若抽象类仅含抽象方法,应直接改为接口;若含大量字段和构造逻辑,说明它已承担过多职责,需拆分
接口 vs 抽象类:选型决策清单
团队需共识何时用接口、何时用抽象类,避免随意混用导致架构模糊。关键看三点:是否需要共享代码、是否需要定义状态、是否允许多重继承。
- 用接口:定义行为契约(如可排序、可序列化)、支持多实现(一个类可实现多个接口)、未来可能由不同技术栈提供(如 DB / Redis / Mock 实现同一 Repository 接口)
- 用抽象类:封装公共初始化逻辑(如连接池创建)、统一日志/监控模板、提供部分默认实现(如 BaseController 中统一处理异常返回格式)
- 禁止:让抽象类实现接口再强制子类重写——这违背抽象类“提供基础”的本意;应把契约放接口,骨架放抽象类,两者正交配合
包结构与层级中的体现
命名规范需落实到包路径,让开发者一眼识别类型角色。接口与抽象类不应散落在各处,而应有清晰归位。
- 接口统一放在 xxx.api 或 xxx.contract 包下(如 com.example.order.api.OrderService)
- 抽象类统一放在 xxx.support 或 xxx.template 包下(如 com.example.order.support.AbstractOrderValidator)
- 具体实现类放在 xxx.impl 或按技术分层(如 xxx.dao.mysql、xxx.service.internal)
- 禁止在 impl 包里定义新接口或抽象类——那是设计阶段的事,不是实现阶段的补丁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











