一、介绍

里氏替换原则的英文名称是:Liskov Substitution Principle,简称LSP。

二、定义

1 继承的优缺点

1 优点
■ 码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;
■ 提高代码的可重用性;
■ 提高代码的可扩展性;
■ 提高产品或项目的开放性。

2 缺点
■ 继承是入侵式的。只要继承,就必须拥有父类的所有属性和方法;
■ 降低代码的灵活性。子类必须拥有父类的属性和方法,使子类受到限制;
■ 增强了耦合性。当父类的常量、变量和方法修改时,必须考虑子类的修改,这种修改可能造成大片的代码需要重构。

2 定义

1 第一种定义:
If for each object o1 of type S there is an object o2 of type T such that for allprograms P defined in terms of S,the behavior of P is unchanged when o1 issubstituted for o2 then T is a subtype of S.

这个定义是最正宗的定义,意思是:如果对一个类型为S的对象o1,都有类型为T的对象o2,使得以S定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型T是类型S的子类型。

2 第二种定义:
Functions that use pointers or references to base classes must be able touse objects of derived classes without knowing it.

第二个定义意思是:所有引用基类的地方必须能透明地使用其子类对象。清晰明确地说明只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道父类还是子类;但是反过来则不可以,有子类的地方,父类未必就能适应。

3 原则

■ 子类必须完全实现父类的方法;
■ 子类可以有自己的个性;
■ 覆盖或实现父类的方法时输入参数可以被放大;
■ 覆盖或实现父类的方法时输出结果可以被缩小。

注意按照里氏替换原则,当多个类之间存在继承关系时,通常应该使用父类或接口来指向子类的对象(除非需要使用子类特有的方法),这更利于提高系统的可扩展性。

在设计模式中体现里氏替换原则的有如下几个模式: 策略模式 、组合模式、 代理模式

三、代码

image.png
image.png
子类需要实现父类的抽象方法

总结:
1)在子类中尽量不要重写父类的非抽象方法。
2)在适当情况下可以通过聚合,组合,依赖来解决问题。