2021-09-05 20:55  阅读(141)
文章分类:设计原则 文章标签:设计原则
©  原文作者:Demo_Null 原文地址:https://cloud.tencent.com/developer/user/1751610

1.1 概述

  里氏替换原则(Liskov Substitution Principle,LSP)由麻省理工学院计算机科学实验室的里斯科夫(Liskov)女士在 1987 年的 "面向对象技术的高峰会议(OOPSLA)"上发表的一篇文章《数据抽象和层次》里提出来的,她提出:继承必须确保超类所拥有的性质在子类中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对实现抽象化的具体步骤的规范。 根据上述理解,对里氏替换原则的定义可以总结如下:  ♞ 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法  ♞ 子类中可以增加自己特有的方法  ♞ 子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松  ♞ 子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的的输出/返回值)要比父类的方法更严格或相等

1.2 优点

 ① 里氏替换原则是实现开闭原则的重要方式之一。  ② 它克服了继承中重写父类造成的可复用性变差的缺点。  ③ 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。  ④ 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。

1.3 案例

  如下图所示,AK47 与 98K 继承了枪械这个类,继承了其开火攻击的方法,但是玩具枪继承枪械类的时候重写开火方法,将攻击改为了发光。士兵在拿武器的时候开到玩具枪确实是继承了 Firearms 类,也有 fire 方法,就直接拿了玩具枪,结果在交战时它发光了!!这不是坑吗,有可能会造成全线崩溃。

202109052055569891.png

  在开发中,此时已经发现了业务调用出现了问题,我们尝试用 instanceof 判断是否是玩具枪来解决,可以发现虽然可以解决但是不划算,万一又来一个玩具枪二号又要重新解决,这种方案直接 pass;二号方案就是直接将玩具枪从 Firearms 剥离出来,新建一个父类 ToyGun,建立委托关系,外形等交给 Firearms 负责,发光交给新类 ToyGun。

202109052055581102.png

  只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。比方说,猫是继承动物类的,以动物的身份拥有吃、喝、跑、叫等行为,可当某一天,我们需要狗、牛、羊也拥有类似的行为,由于它们都是继承于动物,所以只需要更改实例化的地方,程序其他处不需要改变。满足里氏替换原则的子类可以替换父类,但是不能反过来使用父类代替子类。   里氏替换原则诞生的目的就是加强程序的健壮性,同时版本升级也可以做到非常好的兼容性,增加子类,原有的子类还可以继续运行。在我们项目实施中就是每个子类对应了不同的业务含义,使用父类作为参数,传递不同的子类完成不同的业务逻辑,非常完美!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

展开阅读全文

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 七大设计原则之里氏替换原则
上一篇
七大设计原则之依赖倒置原则
下一篇
七大设计原则之开闭原则