跳到主要内容

里氏代换原则(Liskov Substitution Principle, LSP)

定义

里氏替换原则是Barbara Liskov1与1988年提出来的。原文是:

What is wanted here is something like the following substitution property: If for each object of type S there is an object of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when is substituted for then S is a subtype of T

如果对每一个类型为SS的对象O1O_1, 都有类型为TT的对象O2O_2, 使得以T定义的所有程序P在所有的对象O1O_1都代换成O2O_2时, 程序 P 的行为没有发生变化, 那么类型SS是类型TT的子类型。

另一种说法是:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

所有引用基类的地方必须能透明地使用其子类的对象。

核心思想

里氏替代原则是OCP的扩展,遵守LSP就意味着我们在继承基类扩展基类的功能时,不能修改其默认的行为。LSP的违反通常也伴随着OCP的违反。

违反LSP原则的例子

public class Animal {
public void run() {
System.out.println("奔跑");
}

}

public class House extends Animal {

public void sleep() {
System.out.println("马是站着睡觉。");
}
}

public class MickeyMouse extends Animal {

public void run() {
System.out.println("米老鼠是一个玩具,不会奔跑。");
}
}
java

从上面的伪代码中我们可以看出MickeyMouse违反了LSP,因为它改变了父类的行为。同时它也违背了OCP。

在Java中如何防止父类的方法被修改,强制设计满足LSP?答案是,使用final修饰符。

public class Animal {
public final void run() {
System.out.println("奔跑");
}
}
java

使用final修饰符修饰的父类方法不能被子类修改。

同时如果基类中的方法仅供基类使用,不允许子类调用和修改,那么应该设置为private

Footnotes

  1. 芭芭拉·利斯科夫(Barbara Liskov),本名Barbara Jane Huberman。美国计算机科学家,2008年图灵奖得主,2004年约翰·冯诺依曼奖得主。现任麻省理工学院电子电气与计算机科学系教授。