子类的对象提供了父类的所有行为,且加上子类额外的一些东西(可以是功能,可以是属性)。当程序基于父类实现时,如果将子类替换父类而程序不需修改,则说明符合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. Spring boot 异常处理配置

    1.    新建Maven项目 exception 2.   pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0&quo ...

  2. Python -函数的参数定义

    一.函数的参数有四种,位置参数.默认参数.可变参数和关键字参数 def func(x, y=0, *arg, **args): '''x为位置参数 y有默认值 *arg为可变参数 **args为关键字 ...

  3. U盘装CentOS6.4

    1.打开UltraISO,依次点击“文件”>“打开”,选择“CentOS-6.4-i386-bin-DVD1.iso”文件. 2.“启动”>“写入硬盘映像”,在“硬盘驱动器选择u盘”,写入 ...

  4. 【树链剖分 ODT】cf1137F. Matches Are Not a Child's Play

    孔爷的杂题系列:LCT清新题/ODT模板题 题目大意 定义一颗无根树的燃烧序列为:每次选取编号最小的叶子节点形成的序列. 要求支持操作:查询一个点$u$在燃烧序列中的排名:将一个点的编号变成最大 $n ...

  5. 基于PHP的微信公众平台开发(TOKEN验证,消息回复)

    微信公众平台开发 实现步骤: 第一步:填写服务器配置 登录微信公众平台官网后,在公众平台后台管理页面 - 开发者中心页,点击“修改配置”按钮,填写服务器地址(URL).Token和EncodingAE ...

  6. 8-1 python 接口开发(提供数据、返回session_id)

    1.接口开发,根据不同查询条件返回数据库查询结果 import flask import tools import json server = flask.Flask(__name__) #新建一个服 ...

  7. 简单了解,使用oracle中的索引,表分区

    索引的分类 如下: 物理分类 逻辑分类 分区或非分区索引 单列或组合索引 B树索引(标准索引) 唯一或非唯一索引 正常或反向键索引 基于函数索引 位图索引   B树索引 b树索引通常也称为标准索引,索 ...

  8. Pandas基本命令

    关键缩写和包导入 在这个速查手册中,我们使用如下缩写: df:任意的Pandas DataFrame对象 同时我们需要做如下的引入: import pandas as pd 创建测试对象 import ...

  9. Python解压ZIP、RAR等常用压缩格式的方法

    解压大杀器 首先祭出可以应对多种压缩包格式的python库:patool.如果平时只用基本的解压.打包等操作,也不想详细了解各种压缩格式对应的python库,patool应该是个不错的选择. pato ...

  10. linux基础命令3(man)

    Type:显示指定的命令是那种类型.                                            Linux下有两种模式的时间 date:用于系统时间管理.(软件操作的系统时 ...