Java中继承重构为组合的核心是将“子类is-a父类”的刚性依赖转为“新类has-a成员对象”的柔性组合,需识别语义断点、转移职责、封装细节、构造注入依赖并用策略模式保留多态。

Java 中继承重构时安全拆分,核心是把“必须继承”的刚性依赖,转为“按需装配”的柔性组合。不是简单删掉 extends,而是识别语义断点、转移职责、保留契约,让改动可测、可逆、不破接口。
先判断是否真该拆:看继承是否违背 is-a
如果子类不是父类的一种,只是借了它的方法,就该拆。常见信号包括:
- 子类重写父类方法只是为了“跳过逻辑”或“返回固定值”
- 父类里塞了大量
protected字段或工具方法,子类靠访问实现细节才能工作 - 继承链超过两层,比如
A → B → C → D,中间层(如C)只起分类标签作用,没承载真正复用逻辑 - 子类之间共性极少,差异全靠字段控制(如仅靠
type = "cache"或mode = "retry"区分行为)
拆分四步走:提取、持有、委托、注入
以 ValidatedService extends BaseService 为例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
提取:把校验逻辑单独抽成
ValidationRule接口和若干实现类(如NotNullRule、EmailFormatRule) -
持有:在原
ValidatedService中声明private final ValidationRule rule; -
委托:把原来
super.validate()改为this.rule.validate(input) -
注入:构造器接收
ValidationRule,不 new 实例,便于测试替换
保留多态能力:用策略模式替代继承分支
若原结构靠继承实现不同行为(如 PayPalProcessor、AlipayProcessor 都继承 AbstractPaymentProcessor),拆分后不要丢掉扩展性:
立即学习“Java免费学习笔记(深入)”;
- 定义
PaymentStrategy接口 - 各支付方式实现该接口,互不继承
-
PaymentProcessor持有PaymentStrategy字段,运行时切换 - 新增支付方式只需加个新实现类,不改任何已有类
保障安全:从构造到测试全程可控
继承拆成组合后,初始化和测试方式要同步调整:
- 原继承中靠
super(...)初始化父类状态 → 改为构造器传入完整依赖对象 - 避免在类内部
new任何被拆出的组件,否则无法 mock - 单元测试从“测整个继承链”变成“只测当前类 + mock 依赖”,速度更快、边界更清
- 所有具体实现类建议加
final,防止他人又绕回继承老路

















