当前位置: 首页 > news >正文

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.lryc.cn/news/199893.html

相关文章:

  • 【微信小程序】无纸化会议OA系统之首页搭建
  • 小程序:uniapp解决主包体积过大的问题
  • [opencv]图像和特征点旋转
  • 世界粮食日:宏工科技有对策,赋能食品生产高效可持续发展
  • FutureTask配合Thread实现处理有返回结果的源码、逻辑与架构分析
  • Queue Deque 介绍
  • 机器学习(23)---Boosting tree(课堂笔记)
  • Excel 导出打不开
  • css钟表数字样式
  • 一步一步分析ChatGPT,1 粘性,2 传染性, 3 双边网络效应
  • Arthas(阿尔萨斯):阿里巴巴开源的线上问题诊断工具
  • 由Django-Session配置引发的反序列化安全问题
  • 16-spring AOP核心对象的创建
  • Golang 泛型的介绍
  • RK3568笔记四:基于TensorFlow花卉图像分类部署
  • 甄知科技张礼军:数智化转型助企业破茧成蝶!
  • Golang Map:高效的键值对容器
  • 2023年【电工(高级)】报名考试及电工(高级)模拟考试题
  • 伊朗相关的OilRig组织在为期8个月的网络攻击中针对中东政府
  • 服务器数据恢复-linux+raid+VMwave ESX数据恢复案例
  • 残疾人求助报警器
  • 【Datawhale】扩散模型学习笔记 第一次打卡
  • Spring Boot学习笔记
  • 图像边缘检测--(Sobel、Laplacian、Canny)
  • 【计算机网络笔记】计算机网络性能(2)——时延带宽积、丢包率、吞吐量/率
  • 自学(黑客技术)——网络安全高效学习方法
  • 【Linux】进程概念与进程状态
  • 解决安装nvm以后windows cmd无法找到npm/yarn命令的问题
  • 深入解析Java正则表达式:定义、原理和实例
  • DatenLord前沿技术分享 No.38