里氏替换原则要求子类对象能安全替换父类对象且行为不变;核心是子类不得破坏父类契约,需满足前置条件不增强、后置条件不削弱、不变量守恒等准则。
里氏替换原则(Liskov Substitution Principle,简称 LSP)是 Java 面向对象设计中六大核心原则之一,它的核心就一句话:子类对象必须能够替换父类对象,且程序行为不发生改变。换句话说,只要代码里用到了父类类型的地方,换成它的任意合法子类实例,运行结果应该完全一致、不出错、不反逻辑。
继承不是“能编译通过”就万事大吉。现实中常出现:父类方法语义清晰(比如 setHeight() 只改高不碰宽),子类一重写却悄悄联动修改了宽——外部调用者按父类契约使用,结果出 bug。LSP 就是给继承划一条底线:子类不能偷偷破坏父类已承诺的行为规则。
常见违反场景包括:
ArrayList,子类返回 List 看似合理,但若调用方用了 ArrayList 特有方法就会崩)setWidth() 和 setHeight(),子类重写后两个方法都强制同步边长——这违背了矩形“宽高可独立设置”的隐含契约关键不是“能不能继承”,而是“替换了是否还稳得住”。判断依据很实在:
不变量要守住:父类定义的业务不变量(如“余额不能为负”“ID 一旦设置不可变”),子类必须同样维护getDiscountPrice()),而不是重写 getPrice() 改含义LSP 不是理论清规戒律,而是帮你提前避坑的实践指南:
基本上就这些。它不复杂,但容易忽略;守住了,继承才真正成为助力,而不是埋雷工具。