当前位置: 首页 > 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任意一个。

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

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

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

相关文章:

03 里氏替换原则

官方定义: 里氏替换原则(Liskov Substitution Principle,LSP)是由麻省理工学院计算机科学系教授芭芭拉利斯科夫于 1987 年在“面向对象技术的高峰会议”(OOPSLA)上发表的一篇论文《数据抽象和层次》&#…...

【微信小程序】无纸化会议OA系统之首页搭建

前言 中国政府意识到信息技术的重要性,并开始积极推动信息产业的发展。一系列政策和措施被制定和执行,以促进信息技术的采用和普及,从而推动数字化时代的到来。为了响应国家推行的数字化时代,本篇文章以会议OA系统为背景进行编写…...

小程序:uniapp解决主包体积过大的问题

已经分包但还是体积过大 运行时勾选“运行时是否压缩代码”进行压缩 在manifest.json配置(开启分包优化) "mp-weixin" : {"optimization" : {"subPackages" : true}//.... },在app.json配置(设置组件按需注入…...

[opencv]图像和特征点旋转

本来说这是很简单的一个内容,图像旋转只需要使用opencv中自带的旋转函数即可完成,但是最近在做特征点旋转的时候发现使用内置rotate函数给图像旋转90度,再用getRotationMatrix2D得出的旋转矩阵对特征点旋转,画出来的特征点位置全部…...

世界粮食日:宏工科技有对策,赋能食品生产高效可持续发展

10月16日是世界粮食日。随着全球人口的增长,人们对高品质食品的需求也越来越大,如何实现“更好生产、更好营养”成为了食品生产与供应的重要话题。15年来,宏工科技专注物料处理自动化领域,提供食品物料处理一站式解决方案以提高生…...

FutureTask配合Thread实现处理有返回结果的源码、逻辑与架构分析

文章目录 1.介绍2.使用示例3.执行过程描述4.整体的关系5.涉及到的核心源码(只提取了关键代码)5.1 Callable5.2 RunnableFuture5.3 FutureTask5.4 Thread 1.介绍 FutureTask 能够接收 Callable 类型的参数,用来处理有返回结果的情况。 2.使用…...

Queue Deque 介绍

目录 一. 前言 二. Queue 接口 三. Deque 接口 一. 前言 Java里有一个叫做Stack的类,却没有叫做Queue的类(它是个接口名字)。当需要使用栈时,Java已不推荐使用Stack,而是推荐使用更高效的ArrayDeque;既然…...

机器学习(23)---Boosting tree(课堂笔记)

文章目录 一、知识记录二、题目2.1 题目12.2 题目22.3 答案书写 一、知识记录 二、题目 2.1 题目1 2.2 题目2 2.3 答案书写...

Excel 导出打不开

$filename iconv("UTF-8", "GB2312//IGNORE", 志愿者列表) . - . date(YmdHis) . .xlsx; header(Content-Type: application/vnd.ms-excel); header(Content-Disposition: attachment;filename".$filename."); header(Cache-Control: max-age0)…...

css钟表数字样式

如图: 代码 font-size: 28px;font-family: Yourname;font-weight: 500;color: #00e8ff;...

一步一步分析ChatGPT,1 粘性,2 传染性, 3 双边网络效应

请按照以下三个维度一步一步分析ChatGPT,1 粘性,2 传染性, 3 双边网络效应,比如亚马逊的买家和商家的关系 ChatGPT的分析 1.1. 粘性 (Stickiness) 定义: 粘性是指产品或服务对用户的吸引力,即用户在使用…...

Arthas(阿尔萨斯):阿里巴巴开源的线上问题诊断工具

背景 通常,本地开发环境无法访问生产环境。如果在生产环境中遇到问题,则无法使用 IDE 远程调试。更糟糕的是,在生产环境中调试是不可接受的,因为它会暂停所有线程,导致服务暂停。 开发人员可以尝试在测试环境或者预发环境中复现生产环境中的问题。但是,某些问题无法在不同…...

由Django-Session配置引发的反序列化安全问题

漏洞成因 漏洞成因位于目标配置文件settings.py下 关于这两个配置项 SESSION_ENGINE: 在Django中,SESSION_ENGINE 是一个设置项,用于指定用于存储和处理会话(session)数据的引擎。 SESSION_ENGINE 设置项允许您选择不…...

16-spring AOP核心对象的创建

文章目录 1. aop的几个重要概念2. aop bean definition3. AspectJPointcutAdvisor4.AopConfigUtils5.AnnotationAwareAspectJAutoProxyCreator6. 循环依赖1. aop的几个重要概念 参考官方解释:https://docs.spring.io/spring-framework/docs/5.2.9.RELEASE/spring-framework-r…...

Golang 泛型的介绍

引言 Golang是一种现代的编程语言,以其简洁的语法和高效的性能而闻名。然而,与其他一些编程语言相比,Golang在语言层面上缺乏泛型的支持,这使得在处理不同类型的数据时变得有些困难。在本文中,我们将介绍Golang泛型的…...

RK3568笔记四:基于TensorFlow花卉图像分类部署

若该文为原创文章,转载请注明原文出处。 基于正点原子的ATK-DLRK3568部署测试。 花卉图像分类任务,使用使用 tf.keras.Sequential 模型,简单构建模型,然后转换成 RKNN 模型部署到ATK-DLRK3568板子上。 在 PC 使用 Windows 系统…...

甄知科技张礼军:数智化转型助企业破茧成蝶!

数智化浪潮滚滚向前,正席卷各行各业,带领企业从数字化时代跨入数智化时代。可什么是数智化?如何实现数智化转型?已经成为横亘在无数企业面前的大难题! 事实上,数智化是数字化、AI和业务三个要素的交集&…...

Golang Map:高效的键值对容器

1. 引言 在编程中,我们经常需要使用键-值对来存储和操作数据。Golang中提供了一种高效的键值对容器——Map(映射),它提供了快速的查找和插入操作,是处理大量关联数据的理想选择。本文将介绍Golang中的Map,…...

2023年【电工(高级)】报名考试及电工(高级)模拟考试题

题库来源:安全生产模拟考试一点通公众号小程序 2023年【电工(高级)】报名考试及电工(高级)模拟考试题,包含电工(高级)报名考试答案和解析及电工(高级)模拟考…...

伊朗相关的OilRig组织在为期8个月的网络攻击中针对中东政府

导语 伊朗相关的OilRig组织最近在中东政府中展开了一场长达8个月的网络攻击行动。这次攻击导致了文件和密码的被窃取,并且在其中一次攻击中,攻击者还使用了一种名为PowerExchange的PowerShell后门。据Symantec的威胁猎人团队称,他们在一份与T…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage)&#xff1a…...

线程同步:确保多线程程序的安全与高效!

全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...