设计模式6原则之:里氏替换原则

概念

一个软件实体如果适用一个父类的话,那一定是适用于其子类,所有引用父类的地方必须能透明地使用其子类的对象,子类对象能够替换父类对象,而程序逻辑不变。

什么情况下不符合里氏替换原则?

通常情况下,都是子类和父类都可以实例化,父类的方法被子类重新定义,这一类的实现继承会造成父类和子类间的强耦合,也就是实际上并不相关的属性和方法牵强附会在一起,不利于程序扩展和维护。

四层含义

  1. 子类必须实现父类的抽象的方法,但是不能重写父类的非抽象方法

    如果非要重写父类的方法,原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖、聚合,组合等关系代替。

  2. 子类中可以增加自己特有的方法

  3. 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的形参更宽松

  4. 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格

更普遍的做法

尽量使用对象组合/聚合,而不是使用继承达到软件复用的目的。可以使系统更加的灵活,降低类与类之间的耦合度,一个类的变化对于其他类来说影响相对较少。

继承我们称之为白箱复用,相当于把实现的细节暴露给子类,组合/聚合 也成为黑箱复用,对类之外的对象是无法获取到实现细节的。