怎么理解里氏替换原则(LSP)并防范子类错误覆盖父类逻辑引发的bug

轻雪吖_6953

轻雪吖_6953

2026-06-03

431人浏览

原创

里氏替换原则(lsp)要求子类对象可无损替换父类对象:运行结果必须完全一致,不报错、不崩溃、不改返回值、不增删异常、不破坏状态逻辑,本质是严格遵守行为契约而非语法兼容。

怎么理解里氏替换原则(lsp)并防范子类错误覆盖父类逻辑引发的bug

里氏替换原则(LSP)不是“子类能编译通过就行”,而是要求:只要代码里用的是父类类型,换成任意子类对象,运行结果必须一模一样——不报错、不崩溃、不改返回值、不增删异常、不破坏状态逻辑。它检验的不是语法兼容,而是行为契约是否被严格遵守。

关键看三点:输入、输出、副作用

父类方法对外承诺了什么,子类就得照做,不能悄悄加料或缩水:

  • 前置条件不能收紧:父类允许传 null 或负数,子类就不能突然要求“必须 > 0”;否则调用方原有安全输入,在子类下直接失败
  • 后置条件不能放松:父类文档写明“返回非空 List”,子类就不能返回 Collections.unmodifiableList() 或 null;下游 add() 或 size() 就会崩
  • 副作用和异常必须守约:父类 save() 保证事务原子性且不抛 IOException,子类若拆成两步写库 + 异步刷缓存,或新增 throws SQLException,就已越界

重写非抽象方法是高危操作

父类已提供具体实现的方法,客户端代码很可能依赖其行为细节。一旦子类 @Override,就极大概率违反 LSP:

Buzzy AI
Buzzy AI

一款AI视频创作工具,主要用于AI视频编辑工具,视频版的Photoshop,适合需要提升相关任务效率的用户。

下载
  • 比如父类 withdraw(BigDecimal amount) 返回成功码 "0000",子类改成先查信用额度再冻结账户,抛出 InsufficientCreditException —— 调用方根本没 catch 这个异常
  • 又如父类 setWidth(int w) 和 setHeight(int h) 隐含“彼此独立”的契约,子类 Square 把二者绑死,UI 布局循环调用 setWidth(200) 时,高度也被拉成 200,界面错乱
  • 甚至重写 toString() 或 equals() 也很危险:父类按 id 比较,子类多加 name 字段,HashSet 查不到对象、Map get() 返回 null

防范策略:从设计源头堵漏洞

不靠事后测试补救,而是在建模阶段规避风险:

  • 优先用抽象类或接口代替具体父类继承:把“四边形”定义为 Shape 接口,Rectangle 和 Square 各自实现 getWidth()/getHeight(),不共享 setWidth() 行为
  • 共用逻辑抽离为工具类或策略对象:比如 discount 计算交给 DiscountCalculator 策略,PaymentProcessor 持有它,而非让子类重写 calculateTotal()
  • 用委派(delegation)替代继承:Square 内部持有一个 Rectangle 实例,需要面积时调用其 getArea(),但 setWidth() 自己控制逻辑,不承担“可独立设宽高”的义务
  • 给父类写契约式测试套件:覆盖正常输入、边界值、非法参数、并发调用等场景,所有子类必须 100% 通过同一组测试,CI 流水线自动拦截 LSP 破坏

快速自查:三句话拷问继承关系

不用翻源码,只看调用侧:

  • 把某处 new Parent() 直接换成 new Child(),不改任何调用代码,所有功能是否仍正确?
  • 子类有没有重写父类的非 abstract 方法?如果有,它的输入范围、返回值类型、异常列表、对象状态变化,是否和父类文档/测试完全一致?
  • 有没有地方出现 if (obj instanceof Child) { ((Child)obj).specialMethod(); }?这种类型检查本身就是 LSP 失效的信号

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10297

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7422

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6512

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1124

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

928

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1356

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2709

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20031

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1195

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ThinkPHP6.x API接口--十天技能课堂
ThinkPHP6.x API接口--十天技能课堂

共14课时 | 1.5万人学习

第二十四期_PHP8编程
第二十四期_PHP8编程

共86课时 | 3.7万人学习