避免滥用继承的关键是严格遵循“is-a”业务语义,优先用组合替代继承,确保符合里氏替换原则,慎用模板方法,杜绝为测试或复用而继承。
避免滥用继承的关键,是把“is-a”关系真正落实为业务语义上的严格归属,而不是为了代码复用或结构相似就强行拉关系。
当类之间只是“有”某种能力或行为(比如“汽车有发动机”),而不是“是”某种类型(比如“宝马是汽车”),
就该用组合。继承会把父类的实现细节一并拖进来,耦合太紧;组合则只依赖接口或具体类的行为,更灵活、更易测试。
子类对象必须能无缝替换父类对象,且不改变程序正确性。一旦发现子类要重写父类方法并抛异常、返回 null、缩小参数范围、扩大返回类型,或者不得不在调用前加 instanceof 判断——说明继承已违背 LSP,该重构了。
抽象类本意是定义骨架,但容易变成“所有子类都要改”的中心节点。一旦新增一个钩子方法,就得同步更新全部子类;一旦修改模板逻辑,风险波及整个继承树。
继承不是快捷键。为绕过 private 访问、为少写几个 getter、为 mock 父类方法而继承,都会污染领域模型。单元测试应面向接口或行为,而不是靠继承钻访问漏洞。
基本上就这些。继承本身没错,错的是把它当成万能胶水。想清楚“这个子类真的属于父类的分类体系吗”,比急着写 extends 要紧得多。