1. 定义
里氏替换原则(Liskov Substitution Principle, LSP) 是面向对象设计中的五大原则(SOLID)之一,由 Barbara Liskov 提出。它是继承关系的核心原则,确保子类可以替换父类而不影响程序的正确性。
子类对象必须能够替换父类对象,且替换后程序的行为不会发生变化。
换句话说,如果一个程序使用了一个父类的对象,那么它应该能够使用该父类的任何子类对象,而不会产生错误或意外行为。
2. 里氏替换原则的核心思想
1. 子类必须完全实现父类的行为:
-
子类必须实现父类的所有方法,且不能改变父类的行为。
-
子类可以扩展父类的功能,但不能修改父类的原有功能。
2. 子类不能违背父类的约束:
-
子类的方法参数范围必须与父类一致或更宽松。
-
子类的方法返回值范围必须与父类一致或更严格。
3. 子类不能抛出父类未声明的异常:
- 子类的方法不能抛出父类方法未声明的异常。
3. 违反里氏替换原则的后果
如果子类不能完全替换父类,可能会导致以下问题:
程序行为不一致。
难以维护和扩展。
引入隐藏的 bug。
4. 实现里氏替换原则的方法
1. 使用抽象基类或接口:
- 定义清晰的接口或抽象类,确保子类实现所有必要的行为。
2. 避免子类修改父类的行为:
- 子类只能扩展父类的功能,不能改变父类的核心逻辑。
3. 遵循契约设计:
- 父类定义明确的契约(前置条件、后置条件、不变式),子类必须遵守这些契约。
4. 实例分析
场景描述
假设我们有一个表示矩形的类 Rectangle,它有一个计算面积的方法。现在我们需要支持正方形 Square,正方形是一种特殊的矩形。
违反里氏替换原则的实现
class Rectangle {
protected:
int width, height;
public:
void setWidth(int w) {
width = w; }
void setHeight(int h) {
height = h; }
int getWidth() const {