Java 设计模式(十一) 里氏替换原则(LSP)

里氏替换原则(Liskov Substitution Principle)

LSP的基本概念

  • 定义:

    • 所有引用基类的地方必须能透明地使用其子类的对象
    • 只要父类能出现的地方子类就可出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类(封装造成的多态性)
  • 规范
    • 子类必须完全实现父类的方法

      在类中调用其他类时必然要使用父类或者接口,如果子类中不支持父类中的方法,自然就违背了LSP

    • 子类要有自己的特性
      • 子类是在父类的基础上实现的,有自己的特性
      • 这也就导致了LSP的单向性,在子类能出现的地方,父类未必能够胜任。
      • 比如实际开发中向下转型是不正确的,会抛出ClassCastException异常
    • 覆写实现父类的方法时参数可以被放大
    • 子类中方法的参数的前置条件必须与超类中被覆写的方法的前置条件相同或者更宽松
    • 因为参数类型不同会导致参数列表不同,那么实际上我们在参数类型不同时实现的是重载而非覆写
    • 所以在子类中方法条件更宽松的情况下,因为重载的调用规则,更加匹配严谨的重载会优先调用,也就意味着我们这个重载不会意外地覆盖父类中的方法(比如HashMap比Map类型会优先被匹配,可能会导致重载达到也向覆写一样覆盖了父类的函数,但是显然这是不符合逻辑的),保证了LSP的正确性。
    • 覆写实现父类的方法时的输出结果可以被缩小
      • 这个缩小的具体含义如下:设父类中方法的返回值是T,子类中覆写的方法的返回值是S,那么S要么和T是同类型,要么S是T的子类
      • 因为在LSP下,满足缩小条件条件才能保证返回对象在使用时是安全且完整实现的。
  • 优点:采用LSP能够增强程序的健壮性,版本升级使能够巴证非常好的兼容性,即使增加子类,原有的子类还可以继续运行。

因为对于Java语言,LSP已经实现编译期和语言层级的保证,也就是当违反的时候会抛出异常,我们只需要在覆写和重载时遵循LSP即能保证这一原则的保障。

时间: 2024-10-15 14:59:36

Java 设计模式(十一) 里氏替换原则(LSP)的相关文章

"围观"设计模式(2)--里氏替换原则(LSP,Liskov Substitution Principle)

在面向对象的程序设计中.里氏替换原则(Liskov Substitution principle)是对子类型的特别定义.它由芭芭拉·利斯科夫(Barbara Liskov)在1987年在一次会议上名为"数据的抽象与层次"的演说中首先提出. 里氏替换原则的内容能够描写叙述为: "派生类(子类)对象能够替换其基类(超类)对象被使用." 以上内容并不是利斯科夫的原文,而是译自罗伯特·马丁(Robert Martin)对原文的解读. 其原文为: Let be a prope

"围观"设计模式(2)--里氏替换原则(LSP,Liskov Substitution Principle)

在面向对象的程序设计中,里氏替换原则(Liskov Substitution principle)是对子类型的特别定义.它由芭芭拉·利斯科夫(Barbara Liskov)在1987年在一次会议上名为"数据的抽象与层次"的演说中首先提出. 里氏替换原则的内容可以描述为: "派生类(子类)对象能够替换其基类(超类)对象被使用." 以上内容并非利斯科夫的原文,而是译自罗伯特·马丁(Robert Martin)对原文的解读.其原文为: Let be a property

关于里氏替换原则LSP

一直以来,yqj2065都认为,学习里氏替换原则(Liskov SubstitutionPrinciple.LSP),如同学习下围棋一样,易学难精. 因为易学,所以在<编程导论(Java)>中安排在2.1.1节. 简单地说.子类必须能够替代父类,这在面向对象语言中如同常识.所以紧接其后,在[2.1.2 啊,我看到了多态]中介绍向上造型.多态.改写(override); 所谓难精,我们将继承加以分析,符合LSP的继承有实现继承.拓展继承.接口/协议继承和多继承:在介绍接口与实现分离时,强调什么是

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

前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http://freshbrewedcode.com/derekgreer/2011/12/31/solid-javascript-the-liskov-substitution-principle/ 开闭原则的描述是: Subtypes must be substitutable for their ba

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

里氏替换原则LSP(Liskov Subsituation Principle) 里氏替换原则定义 所有父类出现的地方可以使用子类替换并不会出现错误或异常,但是反之子类出现的地方不一定能用父类替换. LSP的四层含义 子类必须完全实现父类的方法 子类可以自己的个性(属性和方法) 覆盖或实现父类的方法时输入参数可以被放大 覆盖或实现父类的方法时输出结果可以被缩小 LSP的定义含义1--子类必须完全实现父类的方法 假设如下场景:定义一个枪支抽象类,一个场景类,三个枪支实现类,一个士兵类.此处,三个枪

OC之里氏替换原则

1. 里氏替换原则. LSP 子类对象可以替换父类对象的位置,并且程序的功能不受影响. 为什么? 1). 指针是1个父类类型,但是我们确给了指针1个子类对象的地址. 这样做当然是可以的,因为你要1个父类对象,我给了你个子类对象. 子类就是1个父类嘛. 2). 因为父类中的成员子类都有. 只会多不会少. 所以,程序的功能不受影响. 2. 里氏替换原则的表现形式: 当1个父类指针,指向1个子类对象的时候.这里就是里氏替换原则. 3. LSP的好处是什么? 1). 1个指针不仅仅可以存储本类对象的地址

设计模式之里氏代换原则(LSP)

里氏代换原则(Liskov Substitution Principle, LSP) 1 什么是里氏代换原则 里氏代换原则是由麻省理工学院(MIT)计算机科学实验室的Liskov女士,在1987年的OOPSLA大会上发表的一篇文章<Data Abstraction and Hierarchy>里面提出来的,主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中的蕴涵的原理.2002年,我们前面单一职责原则中提到的软件工程大师Robert C. Martin,

设计模式六大原则之里氏替换原则

一.概念: 里氏替换原则:LSP (Liskov Substitution Principle),如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都换成o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型. 通俗的定义:所有引用基类的地方必须能透明地使用其子类的对象. 二.例子: 以浇水为例.人,拿到工具[水管.水桶.瓶子],装水后都可以浇水.[水管.桶.瓶子]都可以获取水.应该有个loadWater方法.有watering 浇水功能

设计模式六大原则(2):里氏替换原则

里氏替换原则 肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型. 定义2:所有引用基类的地方必须能透明地使用其子类的对象. 问题由来:有一功能P1,由