多继承 vs 多接口:对“正交性”的影响

副标题 / 摘要 多继承能直接复用实现,但也容易破坏正交性;多接口更强调行为组合。本文对比两者的工程影响。 目标读者 使用面向对象语言的开发者 关注可维护性与复杂度的工程师 需要设计可组合 API 的团队 背景 / 动机 多继承能快速复用代码,但容易引发菱形继承等复杂问题。 多接口更安全,但需要通过组合实现行为。 核心概念 多继承:继承多个实现 多接口:继承多个行为契约 正交性:特性可以独立组合而不相互干扰 实践指南 / 步骤 优先用接口表达能力 复用实现时优先组合而非继承 避免菱形继承与复杂层级 用测试保证组合行为正确 可运行示例 interface Loggable { void log(String msg); } interface Auditable { void audit(String msg); } class Service implements Loggable, Auditable { public void log(String msg) { System.out.println("log:" + msg); } public void audit(String msg) { System.out.println("audit:" + msg); } public static void main(String[] args) { Service s = new Service(); s.log("hello"); s.audit("hello"); } } 解释与原理 多接口强调能力组合,避免继承链带来的隐式耦合。 多继承虽然更直接,但容易破坏正交性并增加维护成本。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]

为什么组合优于继承:灵活性、可测试性与演进成本

副标题 / 摘要 继承容易让系统变脆,组合让系统更灵活。本文解释为什么组合更适合工程演进,并给出实用示例。 目标读者 写面向对象代码的工程师 负责模块演进与重构的开发者 做代码评审与架构设计的团队 背景 / 动机 继承会把父类的实现细节暴露给子类,容易导致“脆弱基类问题”。 组合通过“把能力作为对象注入”来降低耦合,更易测试与替换。 核心概念 继承(Inheritance):is-a 关系,强耦合 组合(Composition):has-a 关系,弱耦合 脆弱基类问题:父类改动导致子类行为改变 实践指南 / 步骤 优先建接口,延后继承 把可变行为抽成组件 用组合注入行为 通过依赖替换实现测试 只在“稳定共性”时使用继承 可运行示例 class Logger: def log(self, msg: str) -> None: print(msg) class FileSaver: def save(self, data: str) -> None: print("save", data) class ReportService: def __init__(self, logger: Logger, saver: FileSaver): self.logger = logger self.saver = saver def run(self, data: str) -> None: self.logger.log("start") self.saver.save(data) self.logger.log("done") if __name__ == "__main__": svc = ReportService(Logger(), FileSaver()) svc.run("report") 解释与原理 组合让行为可替换(如 Logger 可以换成 Mock)。 继承则把依赖固定在父类上,一旦父类变化,子类难以控制影响。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]