里氏替换原则(LSP)由来:

最早是在 妖久八八 年, 由麻神理工学院得一个女士所提出来的。

定义:

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

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

问题由来:

有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。

新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。

解决方案:

当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。

继承包含这样一层含义:

父类中凡是已经实现好的方法(相对于抽象方法而言),实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义。

继承作为面向对象三大特性之一,在给程序设计带来巨大便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加了对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能会产生故障

举例说明继承的风险,我们需要完成一个两数相减的功能,由类A来负责:

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. B b = new B();
  6. Console.WriteLine("100+20={0}",b.plus(, ));
  7. Console.WriteLine("100-20={0}",b.reduce(, ));
  8. Console.ReadKey();
  9. }
  10. }
  11.  
  12. public class A
  13. {
  14. public int plus(int a, int b)
  15. {
  16. return a + b;
  17. }
  18.  
  19. public int reduce(int a, int b)
  20. {
  21. return a - b;
  22. }
  23. }
  24.  
  25. public class B : A
  26. {
  27. public new int reduce(int a, int b)
  28. {
  29. return a - b + ;
  30. }
  31. }

后来, 我们增加了一个新功能, 要求相减在加上100, 由B类完成该功能。

我们发现原本运行正常的相减功能发生了错误。原因就是类B在给方法起名时无意中重写了父类的方法,造成所有运行相减功能的代码全部调用了类B重写后的方法,

造成原本运行正常的功能出现了错误。在本例中,引用基类A完成的功能,换成子类B之后,发生了异常。

在实际编程中,我们常常会通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的可复用性会比较差,特别是运用多态比较频繁时,

程序运行出错的几率非常大。如果非要重写父类的方法,比较通用的做法是:原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖、聚合,组合等关系代替。

PS: 通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

设计模式六大原则(二):里氏替换原则(Liskov Substitution Principle)的更多相关文章

  1. IOS设计模式的六大设计原则之里氏替换原则(LSP,Liskov Substitution Principle)

    定义 里氏替换原则的定义有两种,据说是由麻省理工的一位姓里的女士所提出,因此以其名进行命名. 定义1:如果对一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1所定义的程序P中在o1全都替换 ...

  2. Java设计模式(4:里氏替换原则和合成复用原则详解

    一.里氏替换原则 如果说实现开闭原则的关键步骤就是抽象化,那么基类(父类)和子类的继承关系就是抽象化的具体实现,所以里氏替换原则就是对实现抽象化的具体步骤的规范.即:子类可以扩展基类(父类)的功能,但 ...

  3. [设计模式]<<设计模式之禅>>关于里氏替换原则

    在面向对象的语言中,继承是必不可少的.非常优秀的语言机制,它有如下优点:● 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性:● 提高代码的重用性:● 子类可以形似父类,但又异于父类,“龙 ...

  4. 设计模式课程 设计模式精讲 3-10 里氏替换原则coding

    1 代码演练 1.1 继承关系判别(是否是真正意义的继承) 1.2 入参控制 1.3 出参控制 1 代码演练 1.1 继承关系判别(是否是真正意义的继承)(其实我觉得这个例子有点牵强) 1.1.1 反 ...

  5. Java设计原则之里氏替换原则

    里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出.其严格表述如下:如果对每一个类型为S的 ...

  6. 深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP

    前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http ...

  7. 北风设计模式课程---里氏替换原则(Liskov Substitution Principle)

    北风设计模式课程---里氏替换原则(Liskov Substitution Principle) 一.总结 一句话总结: 当衍生类能够完全替代它们的基类时:(Liskov Substitution P ...

  8. 【C#设计模式】里氏替换原则

    今天,我们再来学习 SOLID 中的"L"对应的原则:里式替换原则. 里氏替换原则 里氏替换原则(Liskov Substitution Principle):派生类(子类)对象能 ...

  9. [OOD]违反里氏替换原则的解决方案

    关于OOD中的里氏替换原则,大家耳熟能祥了,不再展开,可以参考设计模式的六大设计原则之里氏替换原则.这里尝试讨论常常违反的两种形式和解决方案. 违反里氏替换原则的根源是对子类及父类关系不明确.我们在设 ...

  10. C# 实例解释面向对象编程中的里氏替换原则

    在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...

随机推荐

  1. 概率编程语言(Probabilistic Programming Languages)库 —— edward

    注意:tensorflow api 在 1.1.0 以后迎来重大变化,edward 的稳定版依赖于 tensorflow 1.1.0. edward是一个支持概率建模.推断的 Python 第三方库, ...

  2. 23.IDEA 运行junit单元测试方法

    转自:https://blog.csdn.net/weixin_42231507/article/details/80714716 配置Run,增加Junit 最终配置如下:

  3. 第一次接触正则表达式/^[A-Za-z_][A-Za-z0-9_]{5,15}$/

    /^[A-Za-z_][A-Za-z0-9_]{5,15}$/ /^$/ :完整表达式 ^ :表示以什么开始,或者取反 $ :结束 ^[A-Za-z_] : 以字母开始,无论大小都可以: [^A-Za ...

  4. 963B:Destruction of a Tree

    You are given a tree (a graph with n vertices and n - 1 edges in which it's possible to reach any ve ...

  5. VirtualBox内刚刚安装完Debian9系统,也无法设置共享文件夹。解决的方法就是安装VirtualBox客户端增强包。

    VirtualBox内刚刚安装完Debian9系统,也无法设置共享文件夹.解决的方法就是安装VirtualBox客户端增强包. 1.若直接安装客户端增强包会得到如下提示:root@debian:/op ...

  6. 利用HTTP代理录制Jmeter脚本

    1 測试计划中加入一个线程组1 2在"工作台"-非測试元件-加入"HTTP代理server" port: 代理server的port,默认8080,可自行改动, ...

  7. 最小生成树-并查集-Kruskal-zoj-2048-special judge

    Highways description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has a ...

  8. 我的vim配置记录

    一 总体介绍 配置路径,/etc/vim/vimrc,这个是系统的vim配置,假设一台PC多个用户使用,每一个用户的习惯不同的话,能够使用不同的配置.在用户文件夹下新建一个.vimrc的文件就能够了. ...

  9. HDU1796 How many integers can you find【容斥定理】

    题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=1796 题目大意: 给你一个整数N.和M个整数的集合{A1.A2.-.Am}.集合内元素为非负数(包 ...

  10. Docs-->.NET-->API reference-->System.​Web.​UI-->Control-->Methods-->Find​Control

    https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.control.findcontrol?view=netframework-4.7 ...