大话设计模式-里氏代换原则

里氏代换原则(Liskov Substitution Principle,LSP)

概念

里氏代换原则是面向对象设计的基本原则之一,由美国计算机科学家芭芭拉·利斯科夫(Barbara Liskov)提出。这个原则定义了子类型之间的关系,确保在软件中,我们可以将父类对象替换为子类对象,而不会影响程序的正确性。它在原文中的定义是这样的:如果对每一个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。

简单来说,就是子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能 P2 外,还要保证通过重写父类的方法完成原有功能 P1 时,子类的方法行为要和父类的一致。

而在Java中,我们通常通过继承来创建子类。根据里氏代换原则,我们需要确保子类的行为和父类的行为一致。这意味着:

  1. 子类可以增加新的方法,但是不能覆盖父类的方法改变原有的行为。
  2. 子类可以覆盖父类的方法改进原有的行为,但是结果应该和父类的结果一致。

优缺点

遵循LSP的优点:

  1. 增强可扩展性:如果子类能够替换父类而不改变程序的行为,那么我们可以在不修改现有代码的情况下,通过添加新的子类来扩展系统的功能。
  2. 提高代码的可读性和可维护性:遵循LSP可以使代码更容易理解和维护。因为如果子类和父类的行为一致,那么我们就可以理解子类的行为,而不需要查看子类的实现。
  3. 提高代码的复用性:如果子类可以替换父类,那么我们可以在不同的上下文中复用父类和子类,而不需要担心它们的行为不一致。

违反LSP的坏处:

  1. 破坏封装性:如果子类改变了父类的行为,那么使用父类的代码可能会因为子类的行为不一致而出错。这就破坏了封装性,使得代码的维护变得困难。
  2. 增加代码的复杂性:如果子类和父类的行为不一致,那么我们在理解和使用这些类时,就需要考虑它们的差异,这会增加代码的复杂性。
  3. 降低代码的可扩展性:如果子类改变了父类的行为,那么我们在扩展系统功能时,就需要考虑这些行为的差异,这会降低代码的可扩展性。

例子

假设我们有一个父类Bird和一个子类Penguin

class Bird {void fly() {System.out.println("I can fly");}
}class Penguin extends Bird {@Overridevoid fly() {throw new UnsupportedOperationException("Penguins can't fly");}
}

在这个例子中,PenguinBird的子类,但是它覆盖了fly方法并抛出了异常,因为企鹅不能飞。这违反了里氏代换原则,因为我们不能将Bird对象替换为Penguin对象而不改变程序的行为。
通常来讲,里氏代换原则和依赖倒置原则二者相辅相成,依赖倒置原则也叫依赖倒转原则,在我们后续的文章中有详细介绍。
总的来说,遵循里氏代换原则可以帮助我们设计出更健壮、可维护和可扩展的系统。而违反这个原则可能会导致代码的复杂性增加,维护和扩展变得困难。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/1395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【设计模式】7、decorate 装饰模式

文章目录 七、decorate 装饰模式7.1 饮料:类型配料7.1.1 drink_with_ingredient_test.go7.1.2 drink_with_ingredient.go7.1.3 drink.go 7.2 notifier7.2.1 notifier_decorator_test7.2.2 notifier_decorator7.2.3 notifier 7.3 idraw7.3.1 idraw_test7.3.2 idraw7.…

【人工智能基础】经典逻辑与归结原理

本章节的大部分内容与离散数学的命题、谓词两章重合。 假言推理的合式公式形式 R,R→P⇒PR,R∨P⇒P 链式推理 R→P,P→Q⇒R→QR∨P,P∨Q⇒R∨Q 互补文字:P和P 亲本子句:含有互补文字的子句 R∨P,P∨Q为亲本子句 注意: 必须化成析取范式…

命理八字之电子木鱼的代码实现

#uniapp# #电子木鱼# 不讲废话,上截图 目录结构如下图 功能描述: 点击一下,敲一下,伴随敲击声,可自动点击。自动点击需看视频广告,或者升级VIP会员。 疑点解答: 即animation动画的时候&…

Window中Jenkins部署asp/net core web主要配置

代码如下 D: cd D:\tempjenkins\src\ --git工作目录 dotnet restore -s "https://nuget.cdn.azure.cn/v3/index.json" --nuget dotnet build dotnet publish -c release -o %publishPath% --发布路径

装饰器学习

【一】什么是装饰器 装饰器指的就是为被装饰的对象添加新的功能 器 代表工具 增加后的调用方式不变 在不改变源代码和调用方式的基础上增加额外的新功能 【二】装饰器的用途 对上线后的程序进行新功能的增加和修改 给一个功能增加新的需求或者改变原来的程序运行逻辑 【…

Day08React——第八天

useEffect 概念:useEffect 是一个 React Hook 函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAx请求,更改daom等等 需求:在组件渲染完毕后,立刻从服务器获取频道列表数据…

iOS RACScheduler 使用详解

RACScheduler 是 ReactiveCocoa 框架中的一个关键组件,用于在 iOS 开发中管理任务的并发执行。以下是如何详细使用 RACScheduler 的指南,以 Markdown 格式展示。 主要调度器 主线程调度器 用于在主线程上执行任务,通常用于 UI 更新操作。 …

Java:二叉树(1)

从现在开始,我们进入二叉树的学习,二叉树是数据结构的重点部分,在了解这个结构之前,我们先来了解一下什么是树型结构吧! 一、树型结构 1、树型结构简介 树是一种非线性的数据结构,它是由n(n>…

通用类的中文实体命名识别

中文命名实体识别(Chinese NER)调研:https://github.com/taishan1994/awesome-chinese-ner 论文:Unified Structure Generation for Universal Information Extraction (一统实体识别、关系抽取、事件抽取、情感分析&a…

TCP协议学习记录

TCP协议学习记录 简述 对TCP有诸多疑惑的地方: 1、TCP和socket的关系 2、TCP客户端和服务端如何区分 3、TCP连接的两端,端口号需要一致吗 什么是socket 一种编程抽象 编写程序时,利用socket可以使用TCP;假设现在已经将TCP协议…

Matlab无基础快速上手1(遗传算法框架)

本文用经典遗传算法框架模板,对matlab新手友好,快速上手看懂matlab代码,快速应用实践,源代码在文末给出。 基本原理: 遗传算法(Genetic Algorithm,GA)是一种受生物学启发的优化算法…

在Gtiee搭建仓库传代码/多人开发/个人代码备份---git同步---TortoiseGit+TortoiseSVN

文章目录 前言1.安装必要软件2. Gitee建立新仓库git同步2.1 Gitee建立新仓库2.2 Gitee仓库基本配置2.3 Git方式进行同步 3. TortoiseGitTortoiseSVN常用开发方式3.1 秘钥相关3.2 TortoiseGit拉取代码TortoiseGit提交代码 4. 其他功能探索总结 前言 正常企业的大型项目都会使用…

TR5 - Transformer的位置编码

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目录 前言什么是位置编码1. 定义2. 三角函数3. 位置编码公式4. 位置编码示例 可视化理解位置编码1. 代码实现2. 观察不同位置对应的曲线3. 整句话的位置编码可…

排序 “贰” 之选择排序

目录 ​编辑 1. 选择排序基本思想 2. 直接选择排序 2.1 实现步骤 2.2 代码示例 2.3 直接选择排序的特性总结 3. 堆排序 3.1 实现步骤 3.2 代码示例 3.3 堆排序的特性总结 1. 选择排序基本思想 每一次从待排序的数据元素中选出最小(或最大)的一个…

Guitar Pro简谱输入方法 Guitar Pro简谱音高怎么调整,Guitar Pro功能介绍

一、新版本特性概览 Guitar Pro v8.1.1 Build 17在保留了前版本强大功能的基础上,进一步优化了用户体验和功能性能。新版本主要更新包括以下几个方面: 界面优化:新版界面更加简洁美观,操作更加便捷,即使是初学者也能快…

aixcoder介绍

最近了解了一下国内开源的aixcoder,代码自动补全的工具,可以理解为国内版开源的的copilot。 一开始公司给提供了一个代码自动补全的插件,这几天发现原来用的就是aixcoder,所以专门了解了一下。。 介绍 aiXcoder 是一款基于深度…

在线拍卖系统,基于SpringBoot+Vue+MySql开发的在线拍卖系统设计和实现

目录 一. 系统介绍 二. 功能模块 2.1. 管理员功能模块 2.2. 用户功能模块 2.3. 前台首页功能模块 2.4. 部分代码实现 一. 系统介绍 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系…

Docker - 简介

原文地址,使用效果更佳! Docker - 简介 | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-introduce.html Docker是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 D…

vulfocus靶场couchdb 权限绕过 (CVE-2017-12635)

Apache CouchDB是一个开源数据库,专注于易用性和成为"完全拥抱web的数据库"。它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的NoSQL数据库。应用广泛,如BBC用在其动态内容展示平台&…

串口RS485

1.原理 全双工:在同一时刻可以同时进行数据的接收和数据的发送,两者互不影响 半双工:在同一时刻只能进行数据的接收或者数据的发送,两者不能同时进行 差分信号幅值相同,相位相反,有更强的抗干扰能力。 干…