10 | 泛型:逆变or协变,傻傻分不清?
朱涛

你好,我是朱涛。这节课我们来学习 Kotlin 的泛型(Generics),包括泛型基础、使用处型变、声明处型变以及星投影。
泛型,这个概念在很多编程语言里面都存在。在中大型软件开发当中,我们对泛型的使用也十分频繁,因为它可以让我们在不同类型之间复用相似的逻辑代码。
不管是 Android 领域,还是后端领域,泛型在软件的架构当中都有着举足轻重的地位。只有透彻理解了泛型,我们才能理解各种设计模式,进而才可能设计出合理的软件架构。
然而,想要学好泛型却不是一件容易的事情。这是因为,泛型实在太抽象了。
我们都知道,程序其实是对真实世界的抽象,比如我们在前面实战课里写的计算器程序,现实生活当中就有计算器这个东西,我们想要在电脑里写一个抽象的计算器程序,也不会那么难理解,因为它和现实生活相关。可是泛型,它是对程序的抽象。程序本来就已经够抽象了,我们还要在它的基础上再做一次抽象。
这样一来,泛型和我们真实的物理世界差了两层抽象,因此,泛型对于我们人类来说,会显得尤为虚无缥缈。

不过,程序其实也是源自于生活的。所以在这节课里,我会尽量用生活中的例子来给你解释下 Kotlin 的泛型概念,让你能更直观、更立体地感知到泛型与现实生活的联系,然后,你也能够从这些生活的场景中,更深刻地理解并掌握 Kotlin 的泛型,从而为你将来构建大型软件打好基础。
公开
同步至部落
取消
完成
0/2000
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《朱涛 · Kotlin 编程第一课》,新⼈⾸单¥59
《朱涛 · Kotlin 编程第一课》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(30)
- 最新
- 精选
- 白乾涛我觉得Java的 <? extends T> <? super Object> 语法不抽象呀,相比 kotlin 中的 in out 反而更清晰
作者回复: 也许是角度不一样。这里,我觉得抽象的原因是这样的:Kotlin的in out,我一下就能反应过来,in是参数,out是返回值。但<? extends T> <? super Object>就会让我有点懵,不知道哪个该用在什么地方。
418 - A Lonely CatJava中的协变:<? extends T> Java中的逆变:<? super Object> Java中的“星投影”:<?>
作者回复: 感谢这位同学的补充~
213 - $Kotlin声明处型变无法支持又有in又有out,只能在使用处根据情况型变。
作者回复: 赞~
211 - 白乾涛协变:<? extends T> out-作为返回值-可以读取,不可以写入 逆变:<? super T> in-作为参数-可以写入,不可以读取(只能以Object读取)
作者回复: 很好的总结,赞~
8 - 白乾涛老师,文稿中说下面的代码会报错,实际上并不会报错呀 open class Animal() class Dog : Animal() class Cat : Animal() fun foo(list: MutableList<Animal>) { list.add(Dog()) val animal: Animal = list[0] } fun main() { foo(mutableListOf(Cat())) // 需要父类集合,传入子类集合 }
作者回复: 嗯……确实,编译器把子类又推导成父类集合了。这里应该限定泛型实参的:mutableListOf<Cat>(Cat()) 感谢纠正~
3 - neo从型变的父子关系来分类的话,分为逆变和协变 泛型作为参数,用 in;泛型作为返回值,用 out 这两个条规则有冲突的时候应该怎么办呢
作者回复: 符合条件的话,可以用:@UnsafeVariance。如果泛型真的同时存在读取和写入的话,那么就属于泛型不变性的范畴了,也就是说,它无法支持逆变和协变。
1 - Paul Shan使用处的型变,可以使用星投影,更灵活,但是范围比较小。声明处的型变,解决的是泛型类本身的约束,一次定义,所有使用的地方都受到相应影响,星投影处也不例外,使用处不得修改。个人觉得优先使用声明处的型变,使用处的型变会导致不同的使用处,型变不同的情况,带来额外的复杂性。星投影我在实际中基本没用过,老师能否举一个实际中用星投影能很好解决问题的场景。
作者回复: 使用处,声明处的总结很棒!星投影的使用场景,往往是我们不需要范型的时候。
1 - Renext打卡
作者回复: 加油~
1 - 阶前听雨很赞,基本能分清了,再多看几遍以加深理解。
作者回复: 泛型确实比较抽象,要多体会,加油哈~
1 - louc历史上最好的讲泛型,通俗易懂
作者回复: 看到你的回复我真的很高兴,希望你继续坚持学习下去~
收起评论