LSP原则中的逆变和协变
在复习过程中,LSP原则是个很重要的内容。这里先给出LSP原则的定义。
LSP定义
Functions that use pointers or referrnces to base classes must be able to use objects of derived classes without knowing
it.(所有引用基类的地方必须能透明地使用其子类的对象。)
这个的主要作用就是规范继承时子类的一些书写规则。其主要目的就是保持父类方法不被覆盖。
也就是所有引用父类的地方,替换子类进去,不会有任何影响。
子类必须完全实现父类的方法
子类可以有自己的个性
覆盖或实现父类的方法时输入参数可以被放大
覆盖或实现父类的方法时输出结果可以被缩小
LSP是子类型关系的一个特殊定义,称为(强)行为子类型化。在编程语言中,LSP依赖于以下限制:
前置条件不能强化
后置条件不能弱化
不变量要保持或增强
子类型方法参数:逆变
子类型方法的返回值:协变
异常类型:协变
这里出现了两个生词:协变和逆变。本篇文章主要说一下这俩是啥。
逆变与协变综述:如果A、B表示类型,f(⋅)表示类型转换,≤表示继承关系(比如,A≤B表示A是由B派生出来的子类):
f(⋅)是逆变(contravariant)的,当A≤B时有f(B)≤f(A)成立;
f(⋅)是协变(covariant)的,当A≤B时有f(A)≤f(B)成立;
f(⋅)是不变(invariant)的,当A≤B时上述两个式子均不成立,即f(A)与f(B)相互之间没有继承关系。
协变(Co-variance)
父类型->子类型:越来越具体(specific)。
在LSP中,返回值和异常的类型:不变或变得更具体 。
逆变(Contra-variance)
父类型->子类型:越来越抽象。
参数类型:要相反的变化,不变或越来越抽象。
来看一下应用:
数组是协变的:一个数组A[ ] ,可能包含了A类型的实例或者A的任何子类型的实例
1 Number[] numbers = new Number[2];
2 numbers[0] = new Integer(10);
3 numbers[1] = new Double(3.14);
4
5 Integer[] myInts = {1,2,3,4};
6 Number[] myNumber = myInts;
7
8 myNumber[0] = 3.14; //run-time error!
第8行会报错的原因是myNumber指向的是一个Integer[] 而不是Number[],对Interger赋值一个double类型的,不是协变
其实在继承中只需要注意LSP原则即可,这是不矛盾的。
对于参数,也就是前置条件,应当逆变,把前置条件范围放宽。
对于返回值,也就是后置条件,应当协变,把后置条件范围缩小。
这两者加起来,也就是规约变强,符合LSP。
LSP原则中的逆变和协变的更多相关文章
- Java中的逆变与协变
看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); ...
- Java中的逆变与协变(转)
看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); ...
- Java中的逆变与协变 专题
结论先行: PECS总结: 要从泛型类取数据时,用extends: 协变 要往泛型类写数据时,用super: 逆变 既要取又要写,就不用通配符(即extends与super都不用) 不变 List&l ...
- OOP中的逆变和协变
逆变和协变在存在于强类型语言中,尽管非常少提及.可是里面蕴含了面向对象的世界观.感谢和我一起讨论这个问题的人. 这里用了C#.Scala的语法作为演示样例.事实上逆变和协变的概念跟语言本身关系不大.事 ...
- C#中的逆变和协变
msdn 解释如下: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类型. 解释的很正确,大致就是这样,不过不够直白. 直白的理解: “协变” ...
- Java中的逆变与协变 很直接不饶弯的讲出来了
```java 协变 extends只能new 辈分比自己低的家伙 List<? extends Number> list001 = new ArrayList<Integer> ...
- Java 逆变与协变的名词说明
最近在研究Thinking in Java的时候,感觉逆变与协变有点绕,特意整理一下,方便后人.我参考于Java中的逆变与协变,但是该作者整理的稍微有点过于概念化,我在这里简单的说一下 我对于协变于逆 ...
- Java 逆变与协变
最近一直忙于学习模电.数电,搞得头晕脑胀,难得今天晚上挤出一些时间来分析一下Java中的逆变.协变.Java早于C#引入逆变.协变,两者在与C#稍有不同,Java中的逆变.协变引入早于C#,故在形式没 ...
- .NET Core CSharp初级篇 1-8泛型、逆变与协变
.NET Core CSharp初级篇 1-8 本节内容为泛型 为什么需要泛型 泛型是一个非常有趣的东西,他的出现对于减少代码复用率有了很大的帮助.比如说遇到两个模块的功能非常相似,只是一个是处理in ...
- .NET 4.0中的泛型逆变和协变
转载自:http://www.cnblogs.com/Ninputer/archive/2008/11/22/generic_covariant.html:自己加了一些理解 随Visual Studi ...
随机推荐
- python3 - Django3.2框架
提示:web开发已有php.java,而python在这方面,没有优势,python的优势在于:爬虫.人工智能.大数据分析等,python在web开发这方面,没必要掌握:版本:稳定版本:3.2(py3 ...
- thirty-one
动态组件 动态切换组件的显示和隐藏 如何实现动态组件的渲染 vue提供了有一个内置的<component>组件,专门用来实现动态组件的渲染.示例代码如下: 使用keep-alive保持状态 ...
- windows下的故障自愈程序,可以实现进程,kafka按时间段判断状态,日志分级
self-healing 1.使用python3.11写的一个故障自愈程序. 2.本程序在window2019 server运行测试通过 3.通过监控java程序里的详细启动包名来判断进程是否存在 4 ...
- Virtualbox EFI 写入startup.nsh
安装好的Debian系统,重启后会因为找不到入口而无法启动.定位grubx64.efi文件,可用ls直接查找或一步一步查找ls fs0:\EFI\debian\grubx64.efi edit fs0 ...
- Python基于粒子群优化的投资组合优化研究|附代码数据
全文链接:http://tecdat.cn/?p=6811 最近我们被客户要求撰写关于粒子群优化的研究报告,包括一些图形和统计输出. 我今年的研究课题是使用粒子群优化(PSO)的货币进位交易组合优化. ...
- clickhouse杂记
1,clickhouse show tables SHOW [TEMPORARY] TABLES [FROM ] [LIKE ''] [LIMIT ] [INTO OUTFILE ] [FORMAT ...
- Vulnhub 靶场 CORROSION: 1
Vulnhub 靶场 CORROSION: 1 前期准备: 靶机地址:https://www.vulnhub.com/entry/corrosion-1,730/ kali攻击机ip:192.168. ...
- tfidf与bm25
https://www.cnblogs.com/johnnyzen/p/11298273.html 前言 本文主要是对TF-IDF和BM25在公式推演.发展沿革方面的演述,全文思路.图片基本来源于此篇 ...
- Win10家庭版安装docker desktop
1.开启Hyper-V在桌面新建hyperv.cmd文件,内容如下: pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*H ...
- Servicemonitor监控自带metrics接口和无metrics接口
前言: servicemonitor监控存在两种情况: 1.有metrics ,创建service+servicemonitor配置 2.无metrics 配置exporter,exporter进行 ...