里氏替换原则源于麻省理工学院的Liskov女士在1988年提出了一个关于继承的原则。提起继承关系,一般情况大家都会说是子类和父类具有is-A关系。如何做?有哪些注意事项?带着上述疑问来学习一下里氏替换原则。

白话版的里氏替换原则释义:如果我们把代码中使用父类对象的地方用子类对象代替,代码还能正常工作。该原则也是我们的设计目标之一。实际操作过程中,需要做到子类不能修改父类既有的功能,只能进行扩展。在编码时特别需要以下几点:

一、子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。抽象方法在C++中指的是纯虚函数,子类是必须要实现的,不然编译器也不会放过你的,报错是必然的。父类已经实现的功能,是可以覆盖的,编译器认为也是OK的。这么做违反了里氏替换原则,也是我们不提倡的。

二、子类中可以增加自己特有的方法。建立子类的初心是扩展父类的功能,这个比较好理解,无须赘述。

三、当子类的方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类方法的输入参数更宽松。这点没有特殊情况下不建议使用,很容易搞出问题。

四、当子类的方法实现父类的方法时(重载/重写或实现抽象方法)的后置条件(即方法的输出/返回值)要比父类更严格或相等。这一点也是不建议使用,原因同上一条。

前两条还是好理解的,后两条相对来说比较晦涩。项目经验和教训告诉大家,在类的继承时,没有特殊应用场景和绝对的把握,不要轻易挑战后两条要求。即使你对后两条应用的比较熟练,在排查问题时也会造成一定的干扰。就版本维护来说,如果其他同事不能把握的话,这些代码变成你祖传的啦,加薪升职有阻碍哟。

举个正常使用类的继承的栗子,供大家参考一下。

李小菜在编写一个动物世界的程序,在处理鲸鱼的时候碰到了难题。众所周知,鲸鱼是一种会游泳的哺乳类动物。让它继承鱼的基类,但是鱼的很多特性是鲸鱼不具备的,比如使用腮进行呼吸、卵生繁殖。让它继承哺乳类的基类,但是鲸鱼会游泳。如果强行让鲸鱼继承鱼类或者哺乳类的话,必然会违反里氏替换规则。

百思不得其解后,李小菜只好来找王大侠。王大侠费了一番周折找到了一个合适的解决方案。王大侠沉重的说:“小菜啊,这个问题是典型的继承问题,要避免继承泛滥。最好的方式是新增水生物种类,并具备游泳属性。鲸鱼类继承哺乳类和水生生物类就可以解决问题“。

问题解决之后,王大虾又给李小菜同学拔了一下高,上升到理论的高度。

如果两个具体的类A,B之间的关系违反了里氏替代原则,假设是从B到A的继承关系,那么根据具体的情况可以在下面的两种重构方案中选择一种:

一、创建一个新的抽象类C,作为两个具体类的基类,将A,B的共同行为移动到C中来解决问题。

二、从B到A的继承关系改为关联关系。

通过此问题,李小菜对王大虾的敬仰之情又加深了一步。

结语

里氏替代原则最主要的优势是可以约束继承泛滥,也是开闭原则的一种体现。在面向对象程序设计时,时刻牢记的原则之一。

里氏替换原则_趣谈设计模式之里氏替代原则相关推荐

  1. 趣谈设计模式 | 策略模式(Strategy):你还在使用冗长的if-else吗?

    文章目录 案例:指挥官AI 策略模式 配合工厂模式 总结 完整代码与文档 案例:指挥官AI 案例可能不符合实际逻辑,仅用于表述设计模式的思想,勿介意 假设我们开发了一款类似全面战争的即时战略游戏,为了 ...

  2. 趣谈设计模式 | 模板方法模式(Template Method):封装不变部分,扩展可变部分

    文章目录 案例:房屋建造 模板方法模式 模板方法模式与策略模式 总结 完整代码与文档 这个设计模式过于简单,所以不是很好举例- 案例:房屋建造 假设我们是建筑公司中的规划者,负责设定建筑方案,在初期我 ...

  3. 趣谈设计模式 | 代理模式(Proxy):利用代理来控制对象的访问

    文章目录 案例:房屋中介 代理模式 代理模式与装饰器模式 代理模式的应用 远程代理 虚拟代理 安全代理 智能引用代理 写时拷贝代理 总结 完整代码与文档 由于代理模式相较于前面的其他设计模式来说更加简 ...

  4. 趣谈设计模式 | 状态模式(State):如何实现游戏中的状态切换?

    文章目录 案例:马里奥积分竞赛 有限状态机 分支逻辑法 查表法 状态模式 状态模式与策略模式 总结 完整代码与文档 案例:马里奥积分竞赛 喜欢马里奥的小伙伴们都应该知道,前不久马里奥为了庆祝35周年, ...

  5. opp原则_浅谈OPP

    了解Java或C#等面向对象编程语言的的程序员比较熟悉类和对象以及OOP. 一谈起OOP,就会想起教科书式的OOP概念:封装.继承.多态.粗浅的解释封装就是对数据进行隐藏:继承就是子类继承父类(cla ...

  6. 关闭windows安全警报_趣谈中医(11)痛泻要方所治痛泻,好比水坝要泄洪,必拉响警报...

    [作者简介]山东中医药大学中医学博士,山东新中鲁中医医院副主任医师. [整理]赵馨,田智涵,山东中医药大学中医八年制. 痛泻要方是<丹溪心法>的一首名方,方由白术.白芍.陈皮.防风4味药物 ...

  7. eplan好看的电缆图表_趣谈 | 那些年我们看过的电气图纸(附CAD/EPLAN区别)

    原标题:趣谈 | 那些年我们看过的电气图纸(附CAD/EPLAN区别) 电气二次回路图是我们工作中必不可少的内容,形形色色的图纸我们见过很多,小编就下面额图纸和大家分享一下,仅作为个人观点,大家的意见 ...

  8. 面向对象设计原则_聊聊面向对象的6大设计原则

    程序员都知道编程有 3 大类:面向过程.面向对象.面向函数.面向对象是被讨论的最多的,个人认为,这是因为 Java 之类的编程语言有强大的用户基础,本质还是因为比较符合人的直觉. 说到面向对象,大家可 ...

  9. 趣谈设计模式 | 桥接模式(Bridge):将抽象与实现分离

    文章目录 案例:跨平台应用开发 桥接模式 总结 完整代码与文档 案例:跨平台应用开发 A公司最近准备开发一组应用合集,目前包括了视频播放器.音乐播放器.文本播放器三种应用,但是在发售前,他们遇到了困难 ...

  10. 趣谈设计模式 | 外观模式(Facade):为子系统提供高粒度接口

    文章目录 案例:自动驾驶飞机 外观模式 总结 完整代码与文档 案例:自动驾驶飞机 随着自动驾驶汽车的大卖,特X拉开始把目标转向飞行领域,打算开发出一款能够完全自动行驶的飞机,系统初步的设计如下 我们将 ...

最新文章

  1. 独家 | 聊天机器人开发中的机器学习(附链接)
  2. c++ opencv 通过网络连接工业相机_OpenCV项目实战之零件缺陷检测(上)
  3. 图像识别中卷积神经网络“卷积”的作用
  4. diff git 代码实现_Git diff 算法
  5. C语言Main函数到底有几种,你真的懂吗?
  6. uniapp 微信小程序打包发布
  7. Java LocalDate类| 带示例的format()方法
  8. idea重写接口没有@override_乐字节|Java8核心实战-接口默认方法
  9. linux socket read 接受缓存为空_Linux直接IO、缓存IO、阻塞与同步?
  10. wlst启动weblogic
  11. 【Windows10】C盘快速扩容小妙招
  12. android 调出键盘表情_keyboard dialog 仿微博表情键盘输入框,keyboarddialog
  13. 【示波器专题】数字示波器的主要指标——带宽
  14. 解决序列长期依赖的法宝——注意力机制
  15. mt管理器主题修改教程_华为微信气泡怎么设置皮肤 微信怎么改猫和老鼠的主题和气泡?...
  16. bilibili封面
  17. NLP 基础应用研究方向简介
  18. WIN10 共享 访问WIN7提示 出现“你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访问
  19. Vimeo视频下载工具
  20. html+word+clou,d3.js – 用d3.wordcloud重绘文字云

热门文章

  1. 针对Web系统常用的功能测试方法浅析
  2. 我是如何在GitHub上开源一个项目的(截图说明) (VS2010可以安装git插件)
  3. Python单下划线与双下划线
  4. Python设计一个游戏类
  5. php做页面编辑器,最牛在线编辑器ueditor在thinkphp框架中的使用方法
  6. mybatis批量写入及批量更新
  7. cocos 发布android 返回值2,用cocos creator打包发布的时候,编译失败是怎么回事?执行命令出错,返回值:1。...
  8. 开工利是!循序渐进~
  9. 计算机行业没有获奖证书简历怎么填,小升初没有奖项证书该如何写简历
  10. mysql 总分区表限制_MySQL分区表的局限和限制详解