当前位置: 首页 > news >正文

里氏替换原则(LSP)

太好了,现在我们来讲解 SOLID 中非常核心的 LSP:里氏替换原则(Liskov Substitution Principle)

我会一步步讲清楚:

  • 什么是 LSP?
  • 为什么重要?
  • 优劣分析
  • Python 正反例子
  • 清晰的结构图(Mermaid)

🧠 一句话定义(LSP)

任何父类出现的地方,都应该可以用它的子类替代,并且不会导致程序逻辑出错。

简化记忆:

子类能替换父类,并保持行为正确。


🎯 为什么需要?

当你用多态写程序(比如用父类来调用子类对象)时:

如果子类违背了父类的行为约定,会导致系统运行时出现不符合预期的错误,就违反了 LSP


✅ 优点 vs ❌ 缺点

优点缺点
子类更符合父类语义设计成本提升
多态行为更安全有时限制了子类个性
程序行为更稳定实现复杂逻辑更麻烦

🔥 常见违反 LSP 的坑

子类复写方法后,行为和父类完全不同、甚至反逻辑。


❌ 违反 LSP 的反面例子

class Bird:def fly(self):print("I can fly")class Ostrich(Bird):def fly(self):raise Exception("I can't fly")  # ❌ 鸵鸟不能飞def let_it_fly(bird: Bird):bird.fly()let_it_fly(Ostrich())  # ❌ 虽然语法对,但运行崩了

问题:

  • OstrichBird,但替换后程序出错 → 违反 LSP

✅ 遵守 LSP 的正确做法(更合理抽象)

from abc import ABC, abstractmethod# 抽象出“会飞的鸟”和“不飞的鸟”
class Bird(ABC):@abstractmethoddef eat(self):passclass Flyable(ABC):@abstractmethoddef fly(self):passclass Sparrow(Bird, Flyable):def eat(self): print("Sparrow eats")def fly(self): print("Sparrow flies")class Ostrich(Bird):def eat(self): print("Ostrich eats")# 没有 fly 方法# ✅ 函数只接受会飞的鸟
def let_it_fly(bird: Flyable):bird.fly()let_it_fly(Sparrow())  # ✅ OK
# let_it_fly(Ostrich())  # ❌ 语法报错,避免运行期出错

通过接口分离 + 更精确抽象,让程序在编译期就避免 LSP 问题。


🧭 结构图(Mermaid)

Bird
+eat()
Flyable
+fly()
Sparrow
+eat()
+fly()
Ostrich
+eat()

🏁 总结口诀

原则理解方式记忆口诀
✅ 里氏替换原则子类能替换父类,行为不崩溃“不是你的儿子,不要继承你”
🚨 如何避免抽象设计精准、使用接口拆分“不要滥用继承,改用组合或接口”

📌 实际应用场景

  • 游戏角色:近战 vs 远程,应分成独立能力而不是强行继承
  • 网络传输协议:TCP vs UDP,公共方法和行为应明确分离
  • 交通工具:汽车 vs 船,不要硬继承“能跑的交通工具”

需要我帮你写一个 支付系统用户系统中角色模型 来体现 LSP 吗?实战会更直观哦。你想继续扩展哪部分?🔍

相关文章:

  • Java 网络安全新技术:构建面向未来的防御体系
  • 强化学习--2.数学
  • 【Java学习】通配符?
  • 内存性能测试方法
  • 如何通过文理工三类AI助理赋能HI,从而,颠覆“隔行如隔山”的旧观念和“十万小时定律”的成长限制
  • 穿越数据森林与网络迷宫:树与图上动态规划实战指南
  • 【CF】Day50——Codeforces Round 960 (Div. 2) BCD
  • AVFormatContext 再分析零
  • 《告别试错式开发:TDD的精准质量锻造术》
  • Vivado FPGA 开发 | 创建工程 / 仿真 / 烧录
  • 分布式事务解决方案
  • 生成对抗网络(GAN, Generative Adversarial Network)​
  • ES6/ES11知识点
  • 深入理解C++类型转换:从基础到高级应用
  • 【前缀和】和为 K 的连续子数组
  • 【iview】es6变量结构赋值(对象赋值)
  • list的迭代器详讲
  • 2025 年最新 Python 语言实现网易企业邮箱邮件推送验证码详细教程(更新中)
  • 【Redis】redis的数据类型、单线程模型和String的使用
  • 19. LangChain安全与伦理:如何避免模型“幻觉“与数据泄露?
  • 古龙逝世四十周年|中国武侠文学学会与多所高校联合发起学术纪念活动
  • 德国联邦议院6日下午将举行总理选举第二轮投票
  • 五一假期上海边检查验出入境人员超61万人次,同比增长23%
  • 五一假期上海境外来沪消费4.55亿元,同比增长211.6%
  • 旧宫新语|瑞琦:再探《古玩图》——清宫艺术品的前世与今生
  • 工信部:加强通用大模型和行业大模型研发布局