Java中的逆变与协变】的更多相关文章

看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); //type mismatch List<? extends Number> list = new ArrayList<Number>(); list.add(new Integer(1)); //error list.add(new Float(1.2f)); //error 有人会…
看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); //type mismatch List<? extends Number> list = new ArrayList<Number>(); list.add(new Integer(1)); //error list.add(new Float(1.2f)); //error 有人会…
结论先行: PECS总结: 要从泛型类取数据时,用extends: 协变 要往泛型类写数据时,用super: 逆变 既要取又要写,就不用通配符(即extends与super都不用) 不变 List<?>是一个泛型,在没有赋值之前,表示它可以接受任何类型的集合赋值,赋值之后就不能往里面添加元素了. List<?>称为通配符集合.它可以接受任何类型的集合引用赋值,不能添加任何元素,但可以remove或clear,并非immutable集合.List<?>一般作为参数来接收外…
```java 协变 extends只能new 辈分比自己低的家伙 List<? extends Number> list001 = new ArrayList<Integer>(); 初始化可以这样但不能添加非空元素 下面演示如何接收 ; ; int limit=page*rows; )*rows+; List<Integer> list = new ArrayList<>(); list.add(); list.add(); test2(list); r…
逆变和协变在存在于强类型语言中,尽管非常少提及.可是里面蕴含了面向对象的世界观.感谢和我一起讨论这个问题的人. 这里用了C#.Scala的语法作为演示样例.事实上逆变和协变的概念跟语言本身关系不大.事实也是如此. 一.定义 逆变的參数能够由指定的类型的子类型取代,协变的參数能够由指定类型的父类型取代. Scala中的逆变声明:Function[-A,+B] ;当中泛型-A为逆变类型,在实例化时,能够使用A类型或者A类的子类型. 二.协变与逆变的用途不同 1.语义 Scala中,函数的原型之中的一…
msdn 解释如下: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类型. 解释的很正确,大致就是这样,不过不够直白. 直白的理解: “协变”->”和谐的变”->”很自然的变化”->string->object :协变. “逆变”->”逆常的变”->”不正常的变化”->object->string 逆变. OUT 协变   IN 逆变…
最近在研究Thinking in Java的时候,感觉逆变与协变有点绕,特意整理一下,方便后人.我参考于Java中的逆变与协变,但是该作者整理的稍微有点过于概念化,我在这里简单的说一下 我对于协变于逆变的理解 一:协变 协变返回类型指的是子类中的成员函数的返回值类型不必严格等同于父类中被重写的成员函数的返回值类型,而可以是更 "狭窄" 的类型.当然协变也会出现在数据,泛型等地方. 1:协变的简单实例 参考于 “理解Java中的协变返回类型”. 下边代码中,子类方法的返回值类型是父类方法…
最近一直忙于学习模电.数电,搞得头晕脑胀,难得今天晚上挤出一些时间来分析一下Java中的逆变.协变.Java早于C#引入逆变.协变,两者在与C#稍有不同,Java中的逆变.协变引入早于C#,故在形式没有C#直观(Google推出的基于jvm的Kotlin语音,则完全走向了C#的路线).Java中逆变.协变,在泛型集合使用中更多些.更直观(像C#中的用法在Java中较少出现,但并非不可). 正常泛型集合的使用 示例代码如下: public static void main(String[] arg…
.NET Core CSharp初级篇 1-8 本节内容为泛型 为什么需要泛型 泛型是一个非常有趣的东西,他的出现对于减少代码复用率有了很大的帮助.比如说遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据类型,因为方法的参数类型不同.有没有一种办法,在方法中传入通用的数据类型,这样不就可以合并代码了吗? 泛型简介 在我们的C#中,使用泛型对允许您延迟编写类或方法中的编程元素的数据类型的规范,…
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-97讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2土豆:http://www.tudou.com/programs/view/ceac2IoB-ik/优酷:http://v.youku.com/v_show/id_…
转载自:http://www.cnblogs.com/Ninputer/archive/2008/11/22/generic_covariant.html:自己加了一些理解 随Visual Studio 2010 CTP亮相的C#4和VB10,虽然在支持语言新特性方面走了相当不一样的两条路:C#着重增加后期绑定和与动态语言相容的若干特性,VB10着重简化语言和提高抽象能力:但是两者都增加了一项功能:泛型类型的逆变(contravariant)和协变(covariant).许多人对其了解可能仅限于…
该文章中使用了较多的 委托delegate和Lambda表达式,如果你并不熟悉这些,请查看我的文章<委托与匿名委托>.<匿名委托与Lambda表达式>以便帮你建立完整的知识体系. 在C#从诞生到发展壮大的过程中,新知识点不断引入.逆变与协变并不是C#独创的,属于后续引入.在Java中同样存在逆变与协变,后续我还会写一篇Java逆变协变的文章,有兴趣的朋友可以关注一下. 逆变与协变,听起来很抽象.高深,其实很简单.看下面的代码: class Person { } class Stud…
在上篇<Java泛型的协变>这篇文章中遗留以下问题——协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码清单1 /** * * 描 述:Exp3使用逆变<br/> * 作 者:jiaan.gja<br/> * 历 史: (版本) 作者 时间 注释 <br/> * @param itemList */ public void doDecorate3(List<? super…
一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值):逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确. 通常,协变类型参数可用作委托的返回类型,而逆变类型参数可用作参数类型.对于接口,协变类型参数可用作接口的方法的返回类型,而逆变类型参数可用作接口的方法的参数类型. 协变 我们先来看下面一个来自MSDN的例子:01 // 协变 02 IEnumerable<string> strings = new Lis…
一.为什么使用泛型? 泛型其实就是一个不确定的类型,可以用在类和方法上,泛型在声明期间没有明确的定义类型,编译完成之后会生成一个占位符,只有在调用者调用时,传入指定的类型,才会用确切的类型将占位符替换掉. 首先我们要明白,泛型是泛型,集合是集合,泛型集合就是带泛型的集合.下面我们来模仿这List集合看一下下面这个例子: 我们的目的是要写一个可以存放任何动物的集合,首先抽象出一个动物类: //动物类 public class Animal { //随便定义出一个属性和方法 public Strin…
逆变(Contravariance)/协变(Covariance) 1. 基本概念 官方: 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.协变/逆变只支持委托.泛型接口.数组由于历史的原因也支持协变/逆变.在 C# 中,协变和逆变能够实现数组类型.委托类型和泛型类型参数的隐式引用转换. 协变保留分配兼容性,逆变则与之相反.协变允许方法具有的返回类型比接口的泛型类型参数定义的返回类型的派…
scala 逆变和协变的概念网上有很多解释, 总结一句话就是 参数是逆变的或者不变的,返回值是协变的或者不变的. 但是为什么是这样的? 协变: 当s 是A的子类, 那么func(s) 是func(A)的子类. 也就是被参数化类型的泛化方向与参数类型的方向是一致的,所以称为协变. 个人理解的func(s) 是func(A)的子类的意思是: func(s)的返回值是func(A)的返回值的子类. 逆变: 同协变定义,但是是反过来,即当S是A的子类时,func(S)是func(A)的父类. 如下图所示…
为啥需要协变和逆变? 我目前想到的理由是:逆变和协变的目的是支持多态. 一个小例子 不明白为啥输出的是false和true. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace InOutStudy { class Program { static void Main(string[] args)…
MSDN上的说法: 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型----------(注意,这里说的可以使用更具体的类型是指可以给跟具体的类型传递相对不太具体的参数). 泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供更大的灵活性. 在引用类型系统时,协变.逆变和不变性具有如下定义. 这些示例假定一个名为 Base 的基类和一个名为 Derived 的派生类.使你能够使用比原…
EF中的增删改查: 实现步骤: 1.声明一个EF的上下文. bjhksjEntities dbContext = new bjhksjEntities(); 2.声明一个实体. HKSJ_USERS user = new HKSJ_USERS(); user.LoginName = "ssss"; user.Mail = "ssss"; user.PassWord = "ssss"; user.Plane = "ssss";…
一:如何去学习?都去学习什么? 1:学习优秀项目的设计思想,多问几个为什么,为什么要这么设计,这么设计的好处是什么,还能不能在优化 ,如何应用到自己的项目中 2:学习优秀项目的代码风格,代码的封装设计思想,为什么要这么设计,这么设计的好处是什么,还能不能在优化 ,如何应用到自己的项目中,每行代码都要用心去写,每一行代码都要力求使最简洁的 3:学习别人遇到问题是如何分析问题,解决问题的方法是什么 4:遇到新东西应该如何去学习:1:先研究要学习的东西作用是什么 ,有什么好处  2:如何使用:具体的语…
out: 输出(作为结果),in:输入(作为参数) 所以如果有一个泛型参数标记为out,则代表它是用来输出的,只能作为结果返回,而如果有一个泛型参数标记为in,则代表它是用来输入的,也就是它只能作为参数. 逆变不能作为返回类型只能作为参数类型,协变可以作为返回类型但不能作为参数类型…
MSDN上的解释 协变保留兼容性,逆变与之相反 in的使用 个人理解:就是表明泛型就是可以逆变的(逆变就是大变小) // Contravariant interface. interface IContravariant<in A> { } // Extending contravariant interface. interface IExtContravariant<in A> : IContravariant<A> { } // Implementing cont…
今天来学习一下scala中List的构造和类型约束等内容. 让我们来看一下代码 package scala.learn /** * @author zhang */abstract class Big_Data class Hadoop extends Big_Dataclass Spark extends Big_Data object List_Constructor {  def main(args:Array[String]){    val hadoop = new Hadoop ::…
IComparable<Student>是Student的父类,所以IComparable<Student>可以接收Student.但是在使用CompareTo方法的时候,必须传入Student,不允许传入父类IComparable<Student>. public interface IComparable<in T> public class Student : IComparable<Student> { public int Id { g…
package javase; import java.util.ArrayList; import java.util.List; class Animal{ } class Cat extends Animal{ } public class CatIsAnimal { public static void main(String[] args){ Animal am = new Cat(); ArrayList<Cat> aam = new ArrayList<Cat>();…
Java作为面向对象的典型语言,相比于C++而言,对类的继承和派生有着更简洁的设计(比如单根继承). 在继承派生的过程中,是符合Liskov替换原则(LSP)的.LSP总结起来,就一句话: 所有引用基类(父类)的地方必须能够透明地使用其子类的对象. LSP包含四层含义: ① 子类完全拥有父类的方法,且具体子类必须实现父类的抽象方法: ② 子类中可以增加自己的方法: ③ 当子类覆盖或实现父类的方法时,方法的形参要比父类方法的更加宽松: ④ 当子类覆盖或实现父类的方法时,方法的返回值要比父类方法的更…
什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是用一个窄类型替换宽类型,而逆变则是用宽类型覆盖窄类型. 协变:宽类型------>窄类型 逆变:窄类型------>宽类型 class Base{ public Number doStuff(){ return 0; } } class Sub extends Base{ @Override pu…
一.背景 要搞懂Java中的协办与逆变,不得不从继承说起,如果没有继承,协变与逆变也天然不存在了. 我们知道,在Java的世界中,存在继承机制.比如MochaCoffee类是Coffee类的派生类,那么我们可以在任何时候使用MochaCoffee类的引用去替换Coffee类的引用(重写函数时,形参必须与重写函数完全一致,这是一处列外),而不会引发编译错误(至于会不会引发程序功能错误,取决于代码是否符合里氏替换原则). 简而言之,如果B类是A类的派生类,那么B类的引用可以赋值给A类的引用. 赋值的…
一.背景 要搞懂Java中的协办与逆变,不得不从继承说起,如果没有继承,协变与逆变也天然不存在了. 我们知道,在Java的世界中,存在继承机制.比如MochaCoffee类是Coffee类的派生类,那么我们可以在任何时候使用MochaCoffee类的引用去替换Coffee类的引用(重写函数时,形参必须与重写函数完全一致,这是一处列外),而不会引发编译错误(至于会不会引发程序功能错误,取决于代码是否符合里氏替换原则). 简而言之,如果B类是A类的派生类,那么B类的引用可以赋值给A类的引用. 赋值的…