里氏替换原则(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 吗?实战会更直观哦。你想继续扩展哪部分?🔍

相关推荐
DARLING Zero two♡1 个月前
C++类间的 “接力棒“ 传递:继承(上)
开发语言·c++·继承·里氏替换原则
馨谙1 个月前
里氏替换原则
java·开发语言·里氏替换原则
郭涤生1 个月前
Chapters 8&9: OCP and LSP_《clean architecture》notes
算法·里氏替换原则·开闭原则
吴天德少侠3 个月前
里氏替换原则理解
里氏替换原则
Kerwin要坚持日更3 个月前
一文讲解Java中的重载、重写及里氏替换原则
java·里氏替换原则
诸神缄默不语4 个月前
里氏替换原则(Liskov Substitution Principle,LSP):面向对象设计的基本原则
开发语言·里氏替换原则
智驾4 个月前
SOLID原则学习,里氏替换原则
c++·里氏替换原则·solid
ke_wu4 个月前
常见设计原则
接口隔离原则·依赖倒置原则·里氏替换原则·开闭原则·迪米特法则·单一职责原则
Danileaf_Guo4 个月前
MPLS小实验:利用LDP动态建立LSP
里氏替换原则