4、面向对象设计模式之里氏代换原则

Liskov Substitution Principle(里氏代换原则,LSP):子类型(subtype)必须能够替换它们的基本类型。反过来的代换不成立。

例如有两个类,一个类为BaseClass,另一个类是SubClass类,并且SubClass类是BaseClass的子类,那么一个方法如果可以接受一个BaseClass类型的基类对象base的话,如Method1(base),那么它必然可以接受一个BaseClass类型的子类对象sub,Method1(sub)能够正常运行。反过来的代换不成立,如一个方法method2接受BaseClass类型的子类对象sub为参数:method2(sub),那么它一般而言不可以有method2(base),除非是重载方法。

里氏代换原则(Liskov Subsitution Priniciple,LSP)有两种定义方式,第一种定义方式相对严格,其定义如下:

如果对每个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时程序P的行为没有变化,那么类型S是类型T的子类型。

第二种更容易理解的方式定义如下:

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

里氏代换原则可以通俗的表述为:在软件中如果能够使用基类对象,那么一定能够使用其子类对象。把基类都替换成它的子类,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类的话,那么它不一定能够使用基类。

里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类型来对象进行定义,而在运行时在确定其子类行,用子类对象来替换父类对象。

当满足继承的使用,父类肯定存在非私有成员,子类肯定得到了父类的这些非私有成员(假设父类的成员全部是私有的,那么子类没办法从父类继承任何成员,也就不存在继承的概念了)。既然子类继承了父类的这些非私有成员,那么父类对象也就可以在子类对象中调用这些非私有成员。所以,子类对象可以替换父类对象的位置

只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。

由于有了里氏代换原则,才使得开闭原则成为可能。由于子类型替换性才使得使用父类行的模块在无需更改的情况下就可以扩展。否则就不能扩展开放,修改关闭。而依赖导致原则高层模块不依赖低层模块,两者都应该依赖抽象。依赖倒置其实是谁也不依赖谁,除了约定接口,大家可以灵活自如。

 

继承作为面向对象的三大特性之一,给程序带来巨大遍历的同时也带来了一些弊端,它增加了对象之间的耦合性。因此在系统设计时,遵循里氏替换原则,尽量避免子类重写父类的方法,可以有效降低代码出错的可能性。

 

 

  • 添加到短语集
     
    • 没有此单词集: -> ...
       
    • 创建新的单词集...
  • 拷贝
posted @ 2020-05-20 07:10  三里路异乡客  阅读(241)  评论(0编辑  收藏  举报