防止类爆炸需合理划分层级:优先用接口组合正交能力,控制继承深度在三层内,仅对真正is-a关系使用继承,抽象类聚焦共性,接口定义契约,方法单一且职责明确。

防止类爆炸、合理划分层级,关键不是堆叠更多父类,而是让每层继承都有明确语义、可控范围和可维护边界。单纯靠 extends 拉长链路或为每种组合建子类,只会让系统越来越脆。
用接口替代多维继承
当一个类需要同时具备“可打印”“可导出”“带审计日志”等能力时,不要写 PrintOrder、ExportOrder、AuditableOrder 等一堆子类。这些是正交能力,不是类型层级关系。
- 定义小而专注的接口:Printable、Exportable、Auditable
- 具体类按需实现:Order implements Printable, Exportable
- 行为逻辑独立实现,如 PdfPrinter、CsvExporter、DbAuditLogger
- 主类通过字段持有这些能力,而非继承它们
控制继承深度在三层以内
Java 单继承天然限制了纵向扩展能力,但过度拉长(如 A → B → C → D)会让调用路径模糊、调试困难、修改风险放大。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 两层结构最稳妥:Animal → Dog(语义清晰、职责分明)
- 三层需谨慎评估:Animal → Mammal → Dog,仅当 Mammal 确实承载了所有哺乳类共性(如 suckle())且长期稳定
- 超过三层时,优先考虑把中间层拆成组合策略,例如把“哺乳特征”抽成 MammalBehavior 接口,由 Dog 持有
组合优先,只对真正 is-a 关系用继承
继承表达“是什么”,组合表达“有什么”或“用什么”。多数复用场景属于后者。
立即学习“Java免费学习笔记(深入)”;
- Car 不继承 Engine,而是 private final Engine engine
- ReportGenerator 不继承 DatabaseConnection,而是持有一个 DataSource 引用
- PaymentProcessor 不继承各种支付方式,而是注入 PaymentStrategy
- 只有像 CreditCardPayment 是 Payment 的一种时,才用 extends;否则用 strategy.set(new CreditCardPayment())
抽象类聚焦共性,接口定义契约
抽象类适合封装状态与部分实现(如统一 id、createdAt、基础 validate()),接口适合声明能力(如 process()、render()、retry())。
- 抽象基类不实现业务变体,只提供模板方法骨架(如 doProcess() 调用 abstract preCheck() 和 abstract postNotify())
- 把易变逻辑(如校验规则、通知渠道)定义为接口,由子类或外部注入实现
- 避免抽象类实现多个接口——这会混淆纵向共性与横向能力
- 接口方法尽量单一,超 5 个方法就该考虑是否职责过重,拆成更细粒度接口

















