前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >设计模式 ☞ 七大设计原则之里氏替换原则

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

作者头像
Demo_Null
发布于 2020-12-18 06:37:37
发布于 2020-12-18 06:37:37
5720
举报
文章被收录于专栏:Java 学习Java 学习

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。

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/12/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 概述
  • 1.2 优点
  • 1.3 案例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文