一 背景:
里氏替换原则是针对继承的。介绍前先聊聊继承性的特点
继承优势
- 提高代码的复用性(每个子类有拥有父类的属性和方法)
- 提高代码的可扩展性
继承劣势
- 继承是侵入性的(只要继承,就必须拥有父类的属性和方法)
- 继承机制很大的增加了耦合性
继承其实是一把双刃剑 》如何正确合理使用继承呢?》里氏替换原则
二 官方定义
里氏替换原则(Liskov Substitution Principle,LSP)是1988年,麻省理工学院一位姓里的女士提出 的,官方定义如下:
If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T,the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.
如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象
o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
所有引用基类的地方必须能透明地使用其子类的对象
基本介绍
里氏替换原则通俗的来讲:子类可以扩展父类的功能,但是子类不能修改父类原有的功能 ;只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或者异常,使用者可能根本不需要知道是父类还是子类。但是反过来就不行了,有子类出现的地方,父类未必就能适应。
里氏替换原则就是给继承性的使用制定了规范
设计模式之里氏替换原则
- 子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法。
- 子类中可以增加自己特有的方法。
- 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
子类如果方法形参范围变小了,那就是同名,不同参属于重载。也就是不同的方法了。在里氏替换原则要求下,就是子类的输入参数宽于或者等于父类的输入参数,也就是说写的这个方法不会呗调用。
- 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
父类的一个方法返回值是一个类型 T,子类的相同方法(重载重写)的返回值为S,那么里氏替换原则就要去S必须小于等于T,也就是说,要么S和T是同一类型,要么S是T的子类,为什么呢?重写就是同名同参,方法的范围值S小于等于T。这一点是我们一直都遵守的。