里氏替换原则(LSP)

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

我会一步步讲清楚:

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

🧠 一句话定义(LSP)

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

简化记忆:

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


🎯 为什么需要?

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

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


✅ 优点 vs ❌ 缺点

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

🔥 常见违反 LSP 的坑

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


❌ 违反 LSP 的反面例子

python 复制代码
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 的正确做法(更合理抽象)

python 复制代码
from abc import ABC, abstractmethod

# 抽象出"会飞的鸟"和"不飞的鸟"
class Bird(ABC):
    @abstractmethod
    def eat(self):
        pass

class Flyable(ABC):
    @abstractmethod
    def fly(self):
        pass

class 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 吗?实战会更直观哦。你想继续扩展哪部分?🔍

相关推荐
stevenzqzq15 天前
里氏替换原则
android·里氏替换原则
英杰.王15 天前
设计模式-里氏替换原则(Liskov Substitution Principle, LSP)
设计模式·里氏替换原则
科文小白狼1 个月前
Linux下VSCode开发环境配置(LSP)
linux·vscode·里氏替换原则·lsp
我最厉害。,。1 个月前
安卓逆向篇&LSP 模块&HOOK 添加技术&绕过检测&算法解密&逻辑验证
android·里氏替换原则
DARLING Zero two♡3 个月前
C++类间的 “接力棒“ 传递:继承(上)
开发语言·c++·继承·里氏替换原则
馨谙3 个月前
里氏替换原则
java·开发语言·里氏替换原则
郭涤生3 个月前
Chapters 8&9: OCP and LSP_《clean architecture》notes
算法·里氏替换原则·开闭原则
吴天德少侠5 个月前
里氏替换原则理解
里氏替换原则
Kerwin要坚持日更5 个月前
一文讲解Java中的重载、重写及里氏替换原则
java·里氏替换原则