首页 科技正文

台州景点:这一次,终于弄懂了协变和逆变

admin 科技 2020-09-06 44 1

一、前言

刘大胖决议向他的师傅灯笼法师讨教什么是协变和逆变。

 

刘大胖:师傅,最近我在学习泛型接口的时刻看到了协变和逆变,翻了许多资料,可照样不能完全弄懂。

灯笼法师:阿胖,你不要被这些观点弄混,编译器可不知道你说的什么协变逆变。这个问题,首先你得弄懂什么叫类型的可变性。

刘大胖:可变性?

 

二、可变性

灯笼法师:对,可变性是以一种类型平安的方式,将一个工具作为另一工具来引用。虽然是可变,但实在工具的引用地址是不会变的,只是忽悠下编译器。

刘大胖:师傅说的将一个工具作为另一工具来引用?这不就是继续么?

灯笼法师:是的,你可以看下面代码演示(C#):

 

刘大胖:哦,我明白了,由于MemoryStream继续于Stream,以是MemoryStream的工具可以变为Stream的工具,原来我天天在接触可变性,我竟然不知道。

灯笼法师:是的,这种转变实在遵守了里氏替换原则,爱徒,你可还记得?

刘大胖:固然,为了面试早已烂熟于心。里氏替换原则(LSP):指的是所有引用基类的地方都可以使用其子类的工具。可是师傅,这个和协变逆变有什么关系呢?

 

三、协变

灯笼法师:协变和逆变只是可变性的分类,主要用于泛型接口和委托中。协变逆变只是类型转换的偏向差别。我们先看下接口协变吧,如果有Apple类继续于Fruit,如下:

 

灯笼法师:然后现在写了一个打印水果名称的方式,如下:

 

灯笼法师:这时若是你计划打印一些苹果的名称,你会怎么写?

刘大胖:这不是很简单,Apple继续自Fruit,那可以直接使用PrintFruit类了。撸了下,怎么报错了?代码如下:

台州景点:这一次,终于弄懂了协变和逆变 第1张

 

灯笼法师:大胖,你要理清晰,虽然Apple继续Fruit,但List<Apple>和List<Fruit>却一点关系也没有,如图:

台州景点:这一次,终于弄懂了协变和逆变 第2张

 

刘大胖:那若是这样,岂不是要为每一种水果都要界说一个PrintFruit方式,我以为官方不会不知道这个问题吧?

灯笼法师:这种问题,官方固然知道了,以是才有了泛型接口的协变用以支持List<Apple>自动转为List<Fruit>。C#中使用out示意泛型参数的可协变性,List没有out约束,以是不能协变,但它的基类IEnumable却实现了,如图:

台州景点:这一次,终于弄懂了协变和逆变 第3张

 

【译】Java SE 14 Hotspot 虚拟机垃圾回收调优指南

灯笼法师:以是只要把PrintFruit的参数类型换成IEnumable就可以了,如图:

台州景点:这一次,终于弄懂了协变和逆变 第4张

 

刘大胖:那为什么List<T>不能加out以支持协变呢?

灯笼法师:爱徒问的好,List继续于IEnumable,它比IEnumable更宽泛,它支持读和写,但协变只能可读,主要用于约束输出参数。

刘大胖:好吧,我回去再消化下。师傅你再讲一下什么是逆变吧。

 

四、逆变

灯笼法师:逆变是相反的,即支持List<Fruit>转为List<Apple>,泛型接口上添加in约束输入参数。

刘大胖:有点蒙,师傅你照样用代码吧!

灯笼法师:好吧,如果现在我要让苹果列表或桔子列表可以按名称排序,需要一个界说一个水果对照器,此对照器能用于任何种类的水果列表,代码如下:

台州景点:这一次,终于弄懂了协变和逆变 第5张

 

灯笼法师:现在给苹果和桔子列表按名称排序吧,代码如下:

台州景点:这一次,终于弄懂了协变和逆变 第6张

 

刘大胖:师傅你别忽悠我,Sort的参数可是要详细类型的对照器的,你看代码:

台州景点:这一次,终于弄懂了协变和逆变 第7张

 

灯笼法师:大胖,就这是逆变,以使得基类的泛型工具替换子类的泛型工具,主要是因为IComparer<T>中使用了in关键字来约束,代码如下:

台州景点:这一次,终于弄懂了协变和逆变 第8张

 

五、总结

刘大胖:哦,我有点明了了,协变就是支持泛型子类自动转泛型父类,逆变就是支持泛型父类自动转泛型子类。

灯笼法师:也可以这么明白,但这些转换只是针对编译器,其引用地址并没有改变。

 

翻外篇1:

协变:String =>Object

逆变:Object => String

 

翻外篇2:

灯笼法师在刘大胖走后从背后拿出手机,屏幕上显示来不及关闭的知乎APP:

台州景点:这一次,终于弄懂了协变和逆变 第9张

 

 更多精彩文章,可以关注我的民众号:

台州景点:这一次,终于弄懂了协变和逆变 第10张

   ,

诚信在线唯一官网

诚信在线唯一官网(现:阳光在线官网)现已开放诚信在线手机版、诚信在线电脑客户端下载。诚信在线娱乐游戏公平、公开、公正,用实力赢取信誉。

版权声明

本文仅代表作者观点,
不代表本站Allbet的立场。
本文系作者授权发表,未经许可,不得转载。

评论

精彩评论
  • 2020-09-06 00:10:48

    欧博亚洲官方注册欢迎进入欧博亚洲官方注册(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。好看,特别精致的文