接口与抽象类应分层协作:接口定义能力契约并提供极简默认方法,抽象类封装状态与流程实现;方法解析优先级为类自身>父类>接口默认方法;抽象类可作为接口的通用实现载体。

接口默认方法和抽象类不是互斥选项,而是可以分层协作:接口定义能力契约,抽象类封装可复用的状态与流程。
职责分工要清晰
接口应聚焦“能做什么”,比如 PaymentProcessor 声明 process() 和 refund();默认方法只放极简、无状态逻辑,如空参数校验或基础格式转换。抽象类则负责“怎么做”,比如 AbstractCreditCardProcessor 持有卡号加密器、风控客户端等成员变量,并在 process() 中编排调用顺序——这需要构造器初始化和实例字段,接口做不到。
继承链中优先级明确
当一个类同时继承抽象类并实现多个接口时,方法解析有固定顺序:
- 类自身定义的方法最高优先
- 其次为父类(含抽象类)中提供的实现
- 最后才考虑接口的 default 方法
这意味着只要抽象类实现了某个方法,哪怕接口也提供了同名 default 方法,也不会触发冲突,编译器直接采用抽象类版本。
抽象类可作为接口的默认实现载体
常见模式是抽象类实现接口,并提供通用骨架:
-
AbstractList 实现 List 接口,把
size()、isEmpty()等共性逻辑写死,子类只需专注get(int)等核心行为 - 这样既保留接口的多实现能力,又避免每个实现类重复写样板代码
- 如果后续接口新增 default 方法,抽象类可选择覆盖或沿用,不影响已有子类
避免默认方法越界承担
以下情况更适合交给抽象类而非接口 default 方法:
- 需要访问
this或实例字段(接口不能声明非 static final 字段) - 涉及资源初始化(如打开连接、加载配置),需构造器参与
- 逻辑包含条件分支+状态变更,已超出“轻量契约补充”范畴
强行塞进 default 方法,会导致语义模糊、测试困难、难以扩展。

















