03 里氏替换原则

官方定义:

里氏替换原则(Liskov Substitution Principle,LSP)是由麻省理工学院计算机科学系教授芭芭拉·利斯科夫于 1987 年在“面向对象技术的高峰会议”(OOPSLA)上发表的一篇论文《数据抽象和层次》(Data Abstractionand Hierarchy)里提出的.
她在论文中提到:如果S是T的子类型,对于S类型的任意对象,如果将他们看作是T类型的对象,则对象的行为也理应与期望的行为一致

子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏。

如何理解里氏替换原则?

要理解里氏替换原则,其实就是要理解两个问题:
什么是替换?
什么是与期望行为一致的替换(Robert Martin所说的“必须能够替换”)?

1 ) 什么是替换 ?
替换的前提是面向对象语言所支持的多态特性,同一个行为具有多个不同表现形式或形态的能力。
在这里插入图片描述
2 ) 什么是与期望行为一致的替换?
在不了解派生类的情况下,仅通过接口或基类的方法,即可清楚的知道方法的行为,而不管哪种派生类的实现,都与接口或基类方法的期望行为一致。

不需要关心是哪个类对接口进行了实现,因为不管底层如何实现,最终的结果都会符合接口中关于方法的描述(也就是与接口中方法的期望行为一致).
或者说接口或基类的方法是一种契约,使用方按照这个契约来使用,派生类也按照这个契约来实现。这就是与期望行为一致的替换。

场景案例

比如在一个商城项目中,有3种促销活动:
1)PromotionalStrategy (满减活动,两百以上百八折)
2)RebateStrategy(打折活动)
3)ReduceStrategy(返现活动)
在这里插入图片描述

public interface Istrategy {public double realPrice(double consumePrice);
}
public class PromotionalStrategy implements Istrategy {public double realPrice(double consumePrice) {
if (consumePrice > 200) {
return 200 + (consumePrice - 200) * 0.8;
} else {
return consumePrice;
}
}
}
public class RebateStrategy implements Istrategy {
private final double rate;
public RebateStrategy() {
this.rate = 0.8;
}
public double realPrice(double consumePrice) {
return consumePrice * this.rate;
}
}
public class ReduceStrategy implements Istrategy {
public double realPrice(double consumePrice) {
if (consumePrice >= 1000) {
return consumePrice - 200;
} else {
return consumePrice;
}
}
}

调用方为Context,在此类中使用接口定义了一个对象

public class Context {
//使用基类定义对象变量
private Istrategy strategy;
// 注入当前活动使用的具体对象
public void setStrategy(Istrategy strategy) {
this.strategy = strategy;
}
// 计算并返回费用
public double cul(double consumePrice) {
// 使用具体商品促销策略获得实际消费金额
double realPrice =
this.strategy.realPrice(consumePrice);
// 格式化保留小数点后1位,即:精确到角
BigDecimal bd = new BigDecimal(realPrice);
bd = bd.setScale(1, BigDecimal.ROUND_DOWN);
return bd.doubleValue();
}
}

Context 中代码使用接口定义对象变量,这个对象变量可以是实现了lStrategy
接口的PromotionalStrategy、RebateStrategy 、 ReduceStrategy任意一个。

里氏代换原则与多态的区别 ?

虽然从定义描述和代码实现上 来看,多态和里式替换有点类似,但它们关
注的角度是不一样的。多态是面向对象编程的一 大特性,也是面向对象编
程语言的一种语法。它是一种代码实现的思路。而里式替换是一种 设计原
则,用来指导继承关系中子类该如何设计,子类的设计要保证在替换父类
的时候,不 改变原有程序的逻辑及不破坏原有程序的正确性。

里氏替换原则和依赖倒置原则,构成了面向接口编程的基础,正因为里氏替换
原则,才使得程序呈现多样性。

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

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

相关文章

华为数通方向HCIP-DataCom H12-831题库(多选题:1-20)

第01题 如图所示,路由器所有的接口开启OSPF,图中标识的ip地址为设备的Loopback0接口的IP地址,R1、R2,R3的Loopback0通告在区域1,R4的Loopback0通告在区域0、R5的Lopback0通告在区域2,下列哪些IP地址之间可以相互Ping通? A、10.0.3.3和10.0.5.5 B、10.0.4.4和10.0.2.2 …

开源OA协同办公系统,集成Flowable流程引擎 可拖拽创建个性表单

源码下载:https://download.csdn.net/download/m0_66047725/88403340 源码下载2: 关注我留言 开源OA协同办公系统,集成Flowable流程引擎 可拖拽创建个性表单。基于RuoYi-VUE版本开发。 1、使用RuoYi-Vue的基础上开发。 2、集成flowable&a…

卷王问卷考试系统SurveyKing,开源调查问卷和考试系统源码

卷王问卷考试系统/SurveyKing是一个功能最强大的开源调查问卷和考试系统,可以快速部署,并适用于各行业。该系统提供了在线表单设计、数据收集、统计和分析等功能,支持20多种题型,多种创建问卷方式和多种问卷设置。 无论您是需要进…

Android高版本读取沙盒目录apk解析安装失败解决方案

bug场景: 应用内升级下载apk完成后安装,vivo(Android13)手机会报解析包错误,7.0及以上的手机是没问题的。开始以为是v1,v2签名问题导致的,但是我用浏览器下载下来的安装包是能够正确安装的。排除v1,v2签名的…

c++_learning-模板与泛型编程

模板与泛型编程 模板概念、函数模板定义、调用:各种函数:替换失败不是一个错误SFINAE(substitution failure is not an error):由来:特性: *c11引入的类模板enable_if,体现了SFINAE的…

error: unable to read askpass response from

报错信息 解决方法: 中文:文件-->设置-->版本控制-->Git-->勾选使用凭证帮助程序 英文:File -> Settings -> Version Control -> Git / Check "User credential Helper" 因为我的webstrom是中文版的&#…

layui中页面切分

1.引入Split插件 2.切屏比例设置 pallet与material为标签的id 3.html内部标签上设置切分盒子 4参考网站 : 网站链接

zookeeper(目前只有安装)

安装 流程 学kafka的时候安装 Apache ZooKeeper 安装地址:https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz 解压 tar -zxvf kafka_2.12-3.0.0.tgz -C /export/server/ 改配置 cd config cp zoo_sample.cfg z…

2021-arxiv-Prefix-Tuning- Optimizing Continuous Prompts for Generation

2021-arxiv-Prefix-Tuning- Optimizing Continuous Prompts for Generation Paper:https://arxiv.org/pdf/2101.00190.pdf Code:https://github.com/XiangLi1999/PrefixTuning 前缀调优:优化生成的连续提示 prefix-tunning 的基本思想也是想…

JUC并发编程——线程池学习:基础概念及三大方法、七大参数、四大拒绝策略(基于狂神说的学习笔记)

线程池 池化技术的本质:事先准备好一些资源,线程复用,用完即还,方便管理 默认大小:2 最大并发数max 根据电脑去设置,CPU密集型,IO密集型 线程池的好处: 降低资源的消耗提高响应的…

leetcode - 319. Bulb Switcher

Description There are n bulbs that are initially off. You first turn on all the bulbs, then you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it’s off or turning off if it’s on). For the ith round, you toggl…

中文编程开发语言工具编程实际案例:美发店会员管理系统软件编程实例

中文编程开发语言工具编程实际案例:美发店会员管理系统软件编程实例 中文编程开发语言工具编程实际案例:美发店会员管理系统软件编程实例。 软件功能: 1、系统设置:参数设定,账号及权限设置,系统初始化&a…

es6(三)——常用es6(函数、数组、对象的扩展)

ES6的系列文章目录 第一章 Python 机器学习入门之pandas的使用 文章目录 ES6的系列文章目录0、数值的扩展一、函数的扩展1、函数的默认值2、函数的reset参数 二、数组的扩展1. 将对象转成数组的Array.from()2. 将对象转成数组的Array.from()3. 实例方法 find(),fin…

Jmeter性能测试:高并发分布式性能测试

一、为什么要进行分布式性能测试 当进行高并发性能测试的时候,受限于Jmeter工具本身和电脑硬件的原因,无法满足我们对大并发性能测试的要求。 基于这种场景下,我们就需要采用分布式的方式来实现我们高并发的性能测试要求。 二、分布式性能…

Hadoop3教程(二十五):Yarn的多队列调度器使用案例

文章目录 (136)生产环境多队列创建&好处(137)容量调度器多队列提交案例如何创建多个队列如何向指定队列提交任务 (138)容量调度器任务优先级(139)公平调度器案例参考文献 &#…

高校教务系统登录页面JS分析——华东交通大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文,你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习,勿用于非法用途。 一、密码加…

使用 VS Code 作为 VC6 的编辑器

使用 VS Code 作为 VC 6.0 的编辑器 由于一些众所周知的原因,我们不得不使用经典(过时)的比我们年龄还大的已有 25 年历史的 VC 6.0 来学习 C 语言。而对于现在来说,这个经典的 IDE 过于简陋,并且早已不兼容新的操作系…

跨境商城源码部署(无货源模式,多语言,多货币)

在互联网发展的背景下,跨境电商成为了全球贸易的重要形式之一。跨境商城源码部署是指将跨境电商平台的源代码部署到服务器上,以便搭建一个完整的跨境商城网站。通过部署源码,可以实现无货源模式、多语言和多货币等功能,为用户提供…

Word标题编号转换为纯文本

一、创建宏 这个要用到宏命令 打开Word文档,按下快捷键AltF8,在“宏名”栏中输入“编号转换为文本”,这是给它起的名字,然后点击“创建”在新打开的窗口上,你会看到光标在闪烁,把下面函数中的4行内容复制粘…

机器学习中参数优化调试方法

1 超参数优化 调参即超参数优化,是指从超参数空间中选择一组合适的超参数,以权衡好模型的偏差(bias)和方差(variance),从而提高模型效果及性能。常用的调参方法有: 人工手动调参 网格/随机搜索(Grid / Random Search) 贝叶斯优…