协回返回类型表示:在导出类中覆盖基类的方法,可以返回基类方法的返回类型的某种导出类。...tiger speak() { return new tiger(); } } panda继承了animal,并且重写了speak()方法,父类的speak()方法的返回值类型是...zoo,而子类重写speak()方法的返回值却是tiger,因为tiger继承了zoo,所以编译器不会报错。...因而也是一种合法的返回类型。
Java SE5中添加协变返回类型,表示在导出类中的被覆盖方法可以返回基类方法的返回类型的某种导出类型。...的导出类小麦磨坊(Mill) * */ public class WheatMill extends Mill { /** * 重写Mill的process()方法 * 协变返回类型允许返回更具体的...Wheat类型,亦即此时的Wheat为协变返回类型 * @return */ Wheat process(){ return new Wheat();...协变返回类型允许返回更具体的Wheat类型 扩: 里氏代换原则(任何基类可以出现的地方,子类一定可以出现) 重写/覆盖规则: 1.重写方法不能比被重写方法限制有更严格的访问级别。...此处的Wheat即成了协变返回类型。 相关下载 点击下载
参考链接: Java covariant返回类型 协变返回类型:子类覆写了父类的一个方法,子类中方法的返回值类型可以是父类方法返回值类型的子类。...示例代码(Java编程思想)如下所示:子类WheatMill覆写了父类Mill的process方法,子类proces方法的返回值Wheat是父类proces方法返回值Grain的子类。
导读 泛型是Java最基础的语法之一,众所周知:出于安全原因,泛型默认不能支持型变(否则会引入危险),因此Java提供了通配符上限和通配符下限来支持型变,其中通配符上限就泛型协变,通配符下限就是泛型逆变...协变:通配符上限 为了让泛型支持型变,Java引入了通配符上限语法:如果A是B的子类,那么List相当于是List协变的集合只能取出元素,不能添加元素——疯狂Java讲义归纳的口诀是:协变只出不进!...对于更通用的泛型来说,对于支持协变的泛型,程序只能调用以泛型为返回值类型的方法;不能调用形参为泛型的方法。例如如下代码。...extends Number>也是支持协变的泛型,因此该类型的变量只能调用返回值为泛型的方法,不能调用形参为泛型的方法——如上①号代码所示。
背景 文接上回,说到过Java的泛型擦除问题,这块我又联想到一个有意思的考点泛型的协变和逆变。...一、协变 首先Java的数组是协变的,所以假设A是B的父类,那么A[]是可以保存A或者B的对象的,并且A[]是B[]的父类。 ,写谁都会写,子类型限定。...根因是Java的泛型没有协变类型,无法关联起来,也就没有关系。 利用通配符,?代表子类,T为父类。 常见的例子比如,List协变,消费者为逆变。 针对于生产者,可取,有上界;针对于消费者,可存,有下界。...理解它,也可以通过Java的继承关系, 假设存在继承关系Object-》T、T-》A、T-》B; 即T为A、B的父类,协变面向子类;逆变面向Object,它是所有对象的父类。
前言 为什么需要引入逆变、协变和双向协变这些概念 因为考虑到类型兼容,详情参考https://www.typescriptlang.org/docs/handbook/type-compatibility.html...通过协变和逆变原则 协变与逆变(covariance and contravariance)是在计算机科学中,描述具有父/子型别关系的多个型别通过型别构造器、构造出的多个复杂型别之间是否有父/子型别关系的用语...维基百科上关于协变和逆变的解释有点晦涩难懂。...TS 中,函数参数是双向协变的。...设置之后,函数参数就不再是双向协变的了。
写在前面 ---- 和小伙伴分享一些java小知识点,主要围绕下面几点: 什么是逆变(contravariant)&协变(covariant)? 数组支持协变&逆变吗? 泛型支持协变&逆变吗?...下面们结合代码就数组和泛型的协变和逆变进行分析 我们来看一段代码 package com.liruilong; import java.util.Arrays; /** * @Project_name...super Integer> li = new ArrayList(); 关于协变逆变就和小伙伴分享到这里,嗯,还有协变逆变方法,这里要简单说明下 协变方法: 即子类的方法返回值的类型比父类方法要窄...//子类的doStuff()方法返回值的类型比父类方法要窄,即该方法为协变方法,也称多态。...:子类的方法返回值的类型比父类方法宽,此时为逆变方法。
协变返回类型 在 Java SE5 中,添加了协变返回类型,它表示在导出类中的被覆盖的方法可以返回基类方法的返回类型的某种导出类型。...对于上述协变返回类型的定义,读起来有些让人吐血,简单点,通过下面的程序理解协变返回类型: package com.hit.chapter8; /** * author:Charies Gavin...如上图所示,展示了使用协变返回类型后的效果。...在 Java SE5 之前,强制导出类中被覆盖的方法必须返回基类方法的返回类型,但是在增加协变返回类型之后,我们可以让在导出类中被覆盖的方法返回基类方法的返回类型的某种导出类型,也就是说可以返回更加具体的返回类型...例如上例中的kind()方法,在 Java SE5 之前,只能返回Plant,但是在使用协变返回类型之后,我们可以直接返回更加具体的Peony类型。
协变返回类型 在 Java SE5 中,添加了协变返回类型,它表示在导出类中的被覆盖的方法可以返回基类方法的返回类型的某种导出类型。...对于上述协变返回类型的定义,读起来有些让人吐血,简单点,通过下面的程序理解协变返回类型: package com.hit.chapter8; /** * author:Charies Gavin...:" + plant); // 使用协变返回类型 flower = new Luoyangred(); plant = flower.kind();...在 Java SE5 之前,强制导出类中被覆盖的方法必须返回基类方法的返回类型,但是在增加协变返回类型之后,我们可以让在导出类中被覆盖的方法返回基类方法的返回类型的某种导出类型,也就是说可以返回更加具体的返回类型...例如上例中的kind()方法,在 Java SE5 之前,只能返回Plant,但是在使用协变返回类型之后,我们可以直接返回更加具体的Peony类型。
在 C# 9.0 里面添加的一个新特性是支持协变返回类型,也就说子类重写了基类的抽象或虚拟方法,可以在返回值里面返回协变的类型,也就是返回值的类型可以是继承原本子类返回值类型的子类。...如以下代码,从 Animal 继承的 Tiger 类重写了 GetFood 方法,但是在 Tiger 的 GetFood 方法的方法返回值和 Animal 的 GetFood 方法定义的不相同...override Meat GetFood() => new Meat(); } 上面两个代码的不同在于 Animal 类使用的是 abstract 或 virtual 的方法被重写,在重写的时候可以返回协变的类...以下是返回值 Food 类型定义 public class Food { } public class Meat : Food { } 可以看到 Meat...是继承 Food 的类型,也就是说允许子类的返回值类型是重写的方法的子类。
协变 在 Java 中,数组是协变的,也就是说,假设有一个基类 Person 和一个 Person 的子类 Student。...那么在 Java 中又该如何表示协变这样的语义呢?...其中,T1 是其参数类型,R 是其返回值类型,可以看出,函数在其参数类型上是逆变的。...语义与协变的情况是类似的。 于是,Scala 和 Java 的型变标记可以进行如下总结 3: Scala Java 解释 +T ?...,就是函数类型在其返回值的类型上协变,在其参数类型上逆变。
(在类型参数前加out)(派生类只是用来输出值) “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型。...“协变”->”和谐的变”->”很自然的变化”->string->object :协变 协变在委托声明中加入out关键字,表示派生类只是用来输出值,避免出现由delegate派生类是平级,它们定义的变量无法相互赋值产生的问题...协变(out)是将派生类对象的引用传入到基类对象,输出派生类的值 逆变(in)是将基类对象的引用传入到派生对象,派生对象只能操作基类部分 接口的协变和逆变 1️⃣ 接口的协变 using System...DoSomething(father); } } 3️⃣ 协变和逆变的隐式强制转换 编译器自动识别某个已构建的委托是协变或是逆变并且自动进行强制转换 using System;...这些类型参数不能用于协变或逆变 delegate T Factory(); // 协变 逆变 不变 大家还有什么问题,欢迎在下方留言
msdn 解释如下: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型。 “逆变”则是指能够使用派生程度更小的类型。 解释的很正确,大致就是这样,不过不够直白。 ...直白的理解: “协变”->”和谐的变”->”很自然的变化”->string->object :协变。 “逆变”->”逆常的变”->”不正常的变化”->object->string 逆变。 ...上面是个人对协变和逆变的理解,比起记住那些派生,类型,原始指定,更大,更小之类的词语,个人认为要容易点。 ...我个人的理解: 因为协变和逆变的英文太复杂了,并没有体现协变和逆变的不同,但是out 和 in 却很直白。...上面演示的是协变,接下来要演示下逆变。
型变 型变是指类型转换后的继承关系。 Kotlin 的型变分为逆变、协变和不变。...2.1 协变 如果 A 是 B 的子类型,并且Generic 也是 Generic 的子类型,那么 Generic 可以称之为一个协变类。...2.1.1 Java 上界通配符 Java 的协变通过上界通配符实现。...2.2.1 Java 下界通配符 Java 的逆变通过下界通配符实现。 下面的代码因为是协变的,无法添加新的对象。...介绍了 Kotlin 的协变、协变和不变的概念和特性,以及 Java 的上界通配符、下界通配符。 该系列的相关文章: Kotlin 泛型之类型擦除
之后又想到了其他一些相关的东西,除了简单地分析如何通过Emit实现EventHandler的类型转换之外,还加上关于Delegate“协变”与“逆变”的一些东西,算是对前一篇文章的完善。...目录 一、从Delegate的“协变”与“逆变”说起 二、EventHandler是否换一种定义方式更好?...四、通过Emit实现EventHandler的类型转换 五、最简单的转换方式 一、从Delegate的“协变”与“逆变”说起 根据Delegate“协变”与“逆变”的原理,对于两个具有相同声明的两个...我们在定义泛型Delegate的时候可以利用C#“协变”与“逆变”,使类型为A对象能够赋值给类型为B的变量。...原则上讲,事件可以是任意类型的Delegate,但是我们使用的事件一般具有如下两个共同点: 不具有返回类型,或者返回类型为void; 有且只有两个输入参数,其一个参数类型为Object,第二个类型是EventArgs
NET 4通过协变和抗变为泛型接口和泛型委托添加了一个重要的扩展。协变和抗变指对参数和返回值的类型进行转换。 ...我们来看下到底什么是协变什么是抗变: 如果某个返回的类型可以由其基类替换,那么这个类型就是支持协变的 如果某个参数类型可以由其派生类替换,那么这个类型就是支持逆变(抗变)的。...我们再看我们开头的概念 如果某个返回的类型可以由其基类替换,那么这个类型就是支持协变的 如果某个参数类型可以由其派生类替换,那么这个类型就是支持逆变(抗变)的。...也就是在某个返回类型可以由其基类替换的时候,也就是支持协变了。注意其关键点。返回类型、由基类替换派生类。 然后我们再看看那抗变也可称为逆变。...协变:(使用关键字out)返回类型可以由其基类所替代的时候,就是支持协变的。 抗变(逆变):(使用关键字in)传入参数类型可以由其派生类所代替的时候,就是支持抗变(逆变)的。
这种子类到父类的转换就是协变。而另外一种类似于父类转向子类的变换,可以简单的理解为逆变。逆变协变可以用于泛型委托和泛型接口,本篇文章我们将讲解C#里逆变和协变的使用。...协变与逆变 协变(共变):泛型委托或泛型接口的类似于父类转向子类的变换; 逆变(反变):泛型委托或泛型接口的类似子类到父类的隐式转换; 逆变与协变用来描述类型转换后的继承关系,其定义:如果A、B表示类型...,和string与Object的父子关系是相反的; 协变和逆变能够实现数组类型、委托类型和泛型类型参数的隐式引用转换。...InterfaceFuncObject = InterfaceFuncInt;//编译失败,值类型不参与协变或逆变 //泛型接口-逆变 InterfaceFuncB变 //数组的协变使派生程度更大的类型的数组能够隐式转换为派生程度更小的类型的数组。
泛型的逆变 定义有如下方法: interface Filter { public boolean test(E element); } //根据传入的filter过滤器过滤列表并返回被过滤的元素...通过逆变,可以让泛型的约束变得更加宽松。 与协变不同,逆变放宽的是对父类的约束,而协变放宽的是对子类的约束。 但同样,逆变放宽类型约束是存在一定代价的: List<?...Object number = list.get(0); //只能作为顶层级的Object类 泛型的协变使用的是 ?...extends 通配符,使得子类型的泛型对象可以进行赋值,但同样会失去调用 add 存储功能时传递该泛型对象的能力: //泛型的协变 List list = new ArrayList(); list.get(0); //无法进行get 逆变与协变的使用场景: 当一个对象只作为泛型的生产者,也就是只取泛型的情况下
泛型接口 和 泛型委托 中使用协变和逆变,下面的内容也主要围绕泛型类型参数的协变和逆变来进行讲解....()),实际上而言, 内部返回的应该是一个 string 类型(d2 -> d1 -> Func, Func 的返回类型是 string), 但是由于 string 类型可以正确的转换为 object...类型, 所以通过调用 d2 返回一个 object 类型是安全的(由内部的 string 类型转换而来) 上面的说明也解释了为何协变类型参数只能作为输出参数的原因,因为只有这样才能保证类型安全,如果不加这个限制...小结: 协变和逆变用于隐式引用转换 协变的关键字为 out,被其修饰的参数类型只能用于输出参数 逆变的关键字为 in,被其修饰的参数类型只能用于输入参数 子类总是可以安全的转为父类是保证协变和逆变类型安全的统一前提...参考资料 协变和逆变 (C#) 泛型中的协变和逆变 深入理解 C# 协变和逆变 理解 C# 泛型接口中的协变与逆变
领取专属 10元无门槛券
手把手带您无忧上云