[设计模式之禅读书笔记]002_设计模式六大原则(二):里氏替换原则(Liskov Substitution Principle)

序言

本节作者用了很大的篇幅来阐述自己对里氏替换原则的理解,而且代码片段也相当翔实。笔者阅读该节之后,认为该节的核心内容可以归结如下:

1. 里氏替换原则的定义

2. 里氏替换原则的规范

里氏替换原则的定义

   里氏替换原则的定义有两种:

   第一种(作者认为是最正宗的,但是却是理解起来稍微有点绕的)

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

   第二种(理解起来最方便的)

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

里氏替换原则的规范

1. 子类必须完全实现父类的方法

2. 子类可以有自己的个性

3. 覆盖和实现父类的方法时,输入参数可以被放大,但不能被缩小

4. 覆盖和实现父类的方法时,输出结果可以被缩小,但不能被放大

   1. 子类必须完全实现父类的方法

   注意,这里说必须完全实现父类的方法,并不是说在子类里必须有父类的方法的实现体。而是要求在子类继承父类后,不能有未实现的方法。这一点其实编译器已经帮我们做好了。但是我们的角度不是技术角度,而是设计角度。

   子类必须完全实现父类的方法在设计上有什么好处呢?里氏替换的核心:父类出现的地方,子类一定可以出现。这就要求父类中定义的方法,子类出现的时候,都必须有实现,否则会出错的。

   2. 子类可以有自己的个性

   当然,子类是可以有自己的个性的,这在自然界也是普遍存在的。而面向对象思想的显示根基就是现实的自然社会,所以这一点无可非议。

   3. 覆盖和实现父类的方法时,输入参数可以被放大,但不能被缩小

   理解这一点可能比较困难,书上的正反两个例子也还不错,但是作者的表达能力还是有限的,不能让人立马就明白。不过,也算不错的了,看两遍就能明白了。

   这一点的意思是什么呢?一句话:

   当覆盖或实现父类方法时,如果输入参数被缩小,那么传入的参数就必然执行子类的函数,这样父类的逻辑就会被覆盖,父类想保留的操作被覆盖,就引起业务上的混乱。

   唉,我的表达能力也不咋地。

   4. 覆盖和实现父类的方法时,输出结果可以被缩小,但不能被放大

   这个跟3是类似的。这里不详述,无非是一些逻辑演变的过程。

posted @ 2012-10-22 22:35  邵贤军  阅读(496)  评论(0编辑  收藏  举报