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

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 方法,就直接拿了玩具枪,结果在交战时它发光了!!这不是坑吗,有可能会造成全线崩溃。

在这里插入图片描述

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

在这里插入图片描述

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值