您的位置:首页 >深入理解Java LSP:子类如何正确扩展父类功能
发布于2026-02-11 阅读(0)
扫一扫,手机访问
里氏替换原则要求子类在父类出现的任何地方行为不破坏原有逻辑,而非仅编译通过;常见违反包括扩大异常、削弱前置条件、加强后置条件,应通过契约测试、模板方法或组合等方式保障。

里氏替换原则不是“只要能编译通过就行”,而是要求子类对象在任何父类出现的地方,行为不破坏原有逻辑。常见错误是:子类重写了 calculateDiscount(),但把原本返回正数的逻辑改成可能返回负数,而下游代码直接用结果做减法,导致价格变正数反而涨价。
ClassCastException 不会出现,但运行时数值错乱、空指针、状态不一致——这类问题往往测试覆盖不到父类上下文save() 方法保证“成功即持久化”,子类就不能改成只写缓存、延迟落库,除非父类契约本身就允许Java 编译器只检查签名,不校验语义。以下操作语法合法,却实质破坏 LSP:
parseJson() 声明抛 IllegalArgumentException,子类重写后抛 IOException —— 调用方没准备捕获后者id != null,子类实现里允许 id == null 并返回默认值,看似友好,但可能掩盖上游传参错误getItems() 返回可修改的 List,子类返回 Collections.unmodifiableList() —— 调用方原逻辑是先 add() 再处理,现在直接 UnsupportedOperationException增强 ≠ 改变契约。真正符合 LSP 的增强,是在父类定义的边界内做扩展:
process() 框架,留空钩子 beforeValidate() 和 afterSave(),子类只覆写钩子,不碰主流程契约PaymentProcessor 持有 FeeCalculator 接口,子类换实现,而非重写 calculateTotal()withdraw() 开头加 assert balance >= amount : "balance check violated";,比静默失败更容易暴露问题没有自动检查工具,但可以低成本拦截大部分问题:
IllegalArgumentException”),所有子类共用同一套测试用例 —— 这比文档可靠得多if (this instanceof SubClass) 分支:这是典型的“向下类型检查”,说明父类抽象已失效,LSP 实际已被放弃真正难的不是写对一个子类,而是在新增第 7 个子类时,还能确保前 6 个的调用逻辑不受影响——这时候契约测试和小步重构比设计模式更重要。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9