面向对象设计原则——里氏代换原则

2023-11-10

        里氏代换原则(Liskov Substitution Principle, LSP):所有引用基类(父类)的地方必须能透明地使用其子类的对象。

        里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。例如:我喜欢动物,那我一定喜欢狗,因为狗是动物的子类;但是我喜欢狗,不能据此断定我喜欢动物,因为我并不喜欢老鼠,虽然它也是动物。

       例如有两个类,一个类为BaseClass,另一个是SubClass类,并且SubClass类是BaseClass类的子类,那么一个方法如果可以接受一个BaseClass类型的基类对象base的话,如:method1(base),那么它必然可以接受一个BaseClass类型的子类对象sub,method1(sub)能够正常运行。反过来的代换不成立,如一个方法method2接受BaseClass类型的子类对象sub为参数:method2(sub),那么一般而言不可以有method2(base),除非是重载方法。

        里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

在使用里氏代换原则时需要注意如下几个问题:

  • 子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。根据里氏代换原则,为了保证系统的扩展性,在程序中通常使用父类来进行定义,如果一个方法只存在子类中,在父类中不提供相应的声明,则无法在以父类定义的对象中使用该方法。
  • 我们在运用里氏代换原则时,尽量把父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,运行时,子类实例替换父类实例,我们可以很方便地扩展系统的功能,同时无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。里氏代换原则是开闭原则的具体实现手段之一。
  • Java语言中,在编译阶段,Java编译器会检查一个程序是否符合里氏代换原则,这是一个与实现无关的、纯语法意义上的检查,但Java编译器的检查是有局限的。

具体实例分析:

比如有家杂货铺,卖各种商品,每种商品都有价格,收银台直接扫描就知道每件商品的价格了,原始结构图如下:

 

 

        对系统进一步分析就会发现,无论是牙膏还是水,卖的时候这个过程都是一样的,都要收费,只是费用不同而已,所以GroceryStore类中的sell方法重复了,而且杂货铺里边的东西不止这两件,还有很多,为了让系统具有更好的扩展性,同时减少代码重复,使用里氏代换原则对其进行重构。

       本例中,可以将卖的具体东西都抽象成商品(product),然后让具体的商品作为子类,GroceryStore类只需要针对商品类(product)进行编程,根据里氏替换原则,能够接受基类对象的地方必然能接受子类对象,以此只需要将sell方法中的参数改成product就可以了,如果需要增加具体商品,可以继承product类就可以了。结构图如下:

        里氏代换原则是实现开闭原则的重要方式之一。在本实例中,在传递参数时使用基类对象,除此以外,在定义成员变量、定义局部变量、确定方法返回类型时都可使用里氏代换原则。针对基类编程,在程序运行时再确定具体子类。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面向对象设计原则——里氏代换原则 的相关文章

  • plsql Developer 设置 优化

    配置文件 PL SQL Developer 安装目录中的 params ini 文件 配置文件中的参数也是命令行参数 同时设置的话 命令行参数优先 这几个是可能会用的 nologon userid user password db inst
  • 版本号命名规范

    最近写文档被完虐 啊摔 老师不满意 还不好意思直接批评我 搞得自己很羞愧 所以我决定了要加强一下写作技能 首先从文件管理方面进行改进 首先就是版本号的管理规范 转自百度文库http wenku baidu com view 0f7d6b24

随机推荐

  • 小白学习kali linux day5(XSS漏洞学习)

    BEEF工具介绍 BEEF工具针对浏览器进行渗透测试 可以进行XSS漏洞攻击和利用 首先安装beef如下 首先安装beef xss工具 之后启动beef工具 绿色框框里为beef密码 可以为123 下图框框内的表示xss漏洞的钩子 ip应该
  • 126-----JS基础-----Location

    一 代码 很简单 看一下即可 注意 01 BOM html的代码在124节的Navigator中 只是一个简单的测试画面而已 自己随便弄一个测试也可以
  • 使用curl命令断点续传下载

    目录 使用curl命令断点续传下载 使用curl命令断点续传下载 curl exe C O
  • attachEvent报错原因

    document attachEvent is not a function出错的原因 报错原因有 1 利用attachEvent 直接在谷歌浏览器打开 我就是犯这种低级错误的 重要事情说三遍 attachEvent是IE浏览器独有的 at
  • IDEA2022.3设置自动生成类的serialVersionUID

    打开IDEA 点击File settings Editor Inspections 搜索seria 把这两个选上 然后点击apply ok 使用 选中你要生成的类 Alt Enter键自动提示 这个时候就有创建提示了
  • 网络TCP建立连接为什么需要三次握手而结束要四次

    举个打电话的例子 A 你好我是A 你听得到我在说话吗 B 听到了 我是B 你听到我在说话吗 A 嗯 听到了 建立连接 开始聊天 TCP连接的释放 四次挥手 数据传输完毕后 双方都可释放连接 最开始的时候 客户端和服务器都是处于ESTABLI
  • 牛客网多组输入问题怎么办?EOF使用方法

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 1 什么是EOF 2 while getchar EOF
  • cocos2dx使用TiledMap模拟3D地图场景----斜45度2D地图的靠墙直线移动

    基于cocos2dx引擎的第三人称射击游戏 角色使用3D模型 地图采用2 5D 定制地图编辑系统抛开不谈 这里最大可能的挖掘现有工具TiledMap的潜力 完成超2 5D地图的实现 使用2D地图高度模拟3D场景 主要有两个要点需要解决 1
  • 面试官:Vue3有了解过吗?能说说跟Vue2的区别吗?

    一 Vue3介绍 关于vue3的重构背景 看看尤大怎么说 Vue 新版本的理念成型于 2018 年末 当时 Vue 2 的代码库已经有两岁半了 比起通用软件的生命周期来这好像也没那么久 但在这段时期 前端世界已经今昔非比了 在我们更新 和重
  • 用python画小花_用python的小海龟 Turtle 画一朵好看又有趣的小花-Go语言中文社区...

    1967年 Daniel G Bobrow Wally Feurzeig Seymour Papert 和 Cynthia Solomon 设计了LOGO编程语言 用一种直观的方式教孩子们学习编程 尽管该语言也可以解决复杂问题 但给大家留下
  • 关系代数内容学习(交、并、差、投影、选择、连接、重命名)

    关系代数 并 差 交 投影选择 笛卡尔积 连接 重命名 什么是关系代数 是一种抽象的数据查询语言 用对关系的运算来表达查询 关系运算符分类 传统的集合运算符 U N 把关系看成元组的集合 所有运算对象必须具有相同的结构 专门的关系运算符 选
  • AJAX学习笔记1发送Get请求

    传统请求有哪些方式 及缺点 传统请求有哪些 1 直接在浏览器地址栏上输入URL 2 点击超连接 a href 上下文 请求地址 超链接请求 a gt 相对路径 a href http www baidu com 超链接请求 a gt 绝对路
  • 进阶高级测试专项,Pytest自动化测试框架总结(三)

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • 电子信息毕设分享 STM32题目项目汇总 - 100例

    文章目录 1前言 2 STM32 毕设课题 3 如何选题 3 1 不要给自己挖坑 3 2 难度把控 3 3 如何命名题目 1前言 更新单片机嵌入式选题后 不少学弟学妹催学长更新STM32和C51选题系列 感谢大家的认可 来啦 以下是学长亲手
  • Pandas库常用函数和操作

    目录 1 DataFrame 处理缺失值 dropna 2 根据某维度计算重复的行 duplicated value counts 3 去重 drop duplicates 4 拼接 1 拼接列 merge 2 拼接行 5 找出在某一特定维
  • PCB Dk、Df和介质损耗

    介电常数Dk Dk即Dielectric constant的简称 中文名叫介电常数 又叫介质常数或介电系数 它是表示绝缘能力特性的一个系数 以字母 表示 在工程应用中 介电常数时常以相对介电常数的形式来表达 而不是绝对值 常见应用有计算阻抗
  • VS2010启动速度变慢和编译速度变慢的解决办法

    以前一直用VC6 0编写C 和MFC程序 速度非常快 后来因为要编64位程序 只能舍弃掉6 0 改VS2010 其实就功能来说 VC6 0真的够用了 VS2010的高级功能从来没用过 刚开始装VS2010的时候运行速度还算可以 但用了不到一
  • 跨线程的信号与槽

    跨线程的信号与槽 接着上面讨论的 我们如何应用驻足在其他线程里的QObject方法呢 Qt提供了一种非常友好而且干净的解决方案 向事件队列post一个事件 事件的处理将以调用我们所感兴趣的方法为主 当然这需要线程有一个正在运行的事件循环 而
  • 【云原生之Docker实战】使用docker部署Halo博客系统

    云原生之Docker实战 使用docker部署Halo博客系统 一 Halo介绍 1 Halo简介 2 Halo特点 3 本次实践说明 二 检查本地docker环境 1 检查docker版本 2 检查docker状态 3 检查docker
  • 面向对象设计原则——里氏代换原则

    里氏代换原则 Liskov Substitution Principle LSP 所有引用基类 父类 的地方必须能透明地使用其子类的对象 里氏代换原则告诉我们 在软件中将一个基类对象替换成它的子类对象 程序将不会产生任何错误和异常 反过来则