子类的对象提供了父类的所有行为,且加上子类额外的一些东西(可以是功能,可以是属性)。当程序基于父类实现时,如果将子类替换父类而程序不需修改,则说明符合LSP原则。

这个解释看的似懂非懂,再看下面更进一步的解释:

函数使用指向父类的指针或引用时,必须能够在不知道子类类型的情况下使用子类的对象。

子类必须能够替换成它们的父类

这其中存在这样的概念:方法调用者(C)和方法提供者(P)。C调用P提供的方法,P的方法返回给C处理的结果。中间的过程C是不需要知道,也不会知道的。当C调用P的方法时,如果将P替换成sub_P的子类,那么C得到的输出结果也是正确的,C无需修改自身。

这里还有个问题是如何满足LSP原则,或者说,什么情况下子类才可以替换父类?要满足LSP原则,需要遵守以下原则:

  1. sub_P必须实现或继承P的所有公共方法,否则C调用P中有,而sub_P中没有的方法,那么运行时就会出错。
  2. sub_P每个方法的输入参数必须和P一样,否则调用父类的代码不能调用子类。
  3. sub_P每个方法的输出必须不比P少,否则基于父类的输出做的处理就无法完成。

第三条中所说的“不比父类少”,是指子类的输出可以比父类多,也就是父类方法的输出是子类方法的子集。

面向对象语言提供的继承,已经天生的满足了1,2两条。除非是子类重写父类的方法,那么就要依照1,2的原则来重写。(重写与重载的区别:重写要求函数名,传参个数\类型,返回值类型必须相同,访问修饰符子类的必须大于父类的。仅函数名相同,其他不同,则为重载。重载是多态的一种实现 详解传送门

从上面的三条原则中可以看出约定只是约束了父类、子类的输入输出,并没有约束中间的处理过程。

经典的LSP例子:长方形与正方形。数学概念中正方形是长方形的特殊情况,也就是说正方形是长方形的子类。但是在面向对象领域中,正方形是不能作为长方形的子类的。因为正方形设置了高就等于设置了宽,设置了宽就等于设置了高。那么按照长方形的计算规则,最终面积将是最后一次设置高或宽的数值的乘积。长方形高5,宽4,面积为20。替换成正方形后,最后一次设置的如果是高的值,那么面积将是25;如果是宽,那么面积将是16。都不等于20。那么就不能用正方形来替换长方形,否则C调用的结果会不同。

七、LSP 里氏替换原则的更多相关文章

  1. 六大设计原则(二)LSP里氏替换原则

    里氏替换原则LSP(Liskov Subsituation Principle) 里氏替换原则定义 所有父类出现的地方可以使用子类替换并不会出现错误或异常,但是反之子类出现的地方不一定能用父类替换. ...

  2. 设计模式原则(2)--Liskov Substitution Principle(LSP)--里氏替换原则

    1.定义: 所有引用基类(父类)的地方必须能透明地使用其子类的对象.这一原则与继承紧密相关.如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的 ...

  3. 第2章 面向对象的设计原则(SOLID):2_里氏替换原则(LSP)

    2. 里氏替换原则(Liskov Substitution Principle,LSP) 2.1 定义 (1)所有使用基类的地方必须能透明地使用子类替换,而程序的行为没有任何变化(不会产生运行结果错误 ...

  4. 里氏替换原则(Liskov Substitution Principle)

    开放封闭原则(Open Closed Principle)是构建可维护性和可重用性代码的基础.它强调设计良好的代码可以不通过修改而扩展,新的功能通过添加新的代码来实现,而不需要更改已有的可工作的代码. ...

  5. .net学习之继承、里氏替换原则LSP、虚方法、多态、抽象类、Equals方法、接口、装箱拆箱、字符串

    1.继承(1)创建子类对象的时候,在子类对象中会为子类对象的字段开辟空间,也会为父类的所有字段开辟空间,只不过父类私有的成员访问不到(2)子类从父类继承父类所有的非私有成员,但是父类的所有字段也会创建 ...

  6. 【面向对象设计原则】之里氏替换原则(LSP)

    里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing 教授于1994年提出,所以使用的是这位女博士的性命名的一个 ...

  7. 里氏替换原则(LSP)

    替换原则由MIT计算机科学实验室的Liskov女士在1987年的OOPSLA大会上的一篇文章中提出,主要阐述有关继承的一些原则,故称里氏替换原则. 2002年,Robert C.Martin出版了一本 ...

  8. 面向对象设计原则三:里氏替换原则(LSP)

    里氏替换原则(LSP)定义:在任何父类出现的地方都可以用它的子类类替换,且不影响功能.解释说明:其实LSP是对开闭原则的一个扩展,在OO思想中,我们知道对象是由一系列的状态和行为组成的,里氏替换原则说 ...

  9. 里氏替换原则(Liskov Substitution Principle) LSP

    using System; using System.Collections.Generic; using System.Text; namespace LiskovSubstitutionPrinc ...

随机推荐

  1. JSONObject数组排序工具类

    依赖jar <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</a ...

  2. Spring 远程调用工具类RestTemplateUtils

    Spring 远程调用Rest服务工具类,包含Get.Post.Put.Delete四种调用方式. 依赖jar <dependency> <groupId>org.spring ...

  3. Spring boot 集成Spring Security

    依赖jar <dependency> <groupId>org.springframework.cloud</groupId> <artifactId> ...

  4. matlab 下载

    Obrazy DVD programu Matlab ke stažení Verze 2015b Verze 2015a Verze 2014b Verze 2014a Verze 2012b Ve ...

  5. 一个老鸟发的公司内部整理的 Android 学习路线图 Markdown 版本

    jixiaohua发了一篇一个老鸟也发了一份他给公司内部小伙伴整理的路线图.另一份 Android 开发学习路线图.可惜不是MarkDown格式的,所以jixiaohua直接上传的截图,在jixiao ...

  6. (排班表二)后台动态绘制Grid表格

    后台动态绘制值班表(Grid表格 列名不固定) 要求:表头除了值班人姓名,还要显示日期,及每天的星期值,用斜杠‘/’分隔.即:几号/星期几 最终实现的效果:根据查询的年月显示每个值班人查询月份每天的值 ...

  7. Java分享笔记:使用keySet方法获取Map集合中的元素

    /*--------------------------- Map集合中利用keySet方法获取所有的元素值: ....keySet方法:将Map中的所有key值存入到Set集合中, ....利用Se ...

  8. vc导出调用dll的两种方式

    一.stdcall 1. #define  DLLEXPORT _declspec(dllexport) _stdcall, int DLLEXPORT func(const char *peer,u ...

  9. 实例:关于ALV控件可编辑的整理

    使ALV控件中的内容可编辑 这应该是一个非常有用的功能,这样我们便可以用它来代替table control来编出一些有这现成功能的界面来.实际上,让alv中的内容可以被编辑与alv的事件无关.但是经常 ...

  10. MySQL 5.7基于GTID的主从复制环境搭建(一主一从)

      Preface       As wel all know,replication base on GTID with row format of binary log is comprehens ...