最早遇到 super 和 extends 的时候没有注意他们的区别,因为也一直没用到过。最近在学习 Kotlin 的时候遇到了逆变、协变(in\out)的概念,决定好好研究一下。
是什么
先拿代码试一下
Kotlin 版本
Java 版本
从代码是否报错可以看出super和in是类似的,extends和out是类似的。那么这两组关键字分别代表什么呢?
在 main 方法中,我们分别将三种 list 传给addInUser/addSuperUser、addOutUser/addExtendsUser
addInUser/addSuperUser只可以接收personList和userList
addOutUser/addExtendsUser只可以接收readerList和userList
也就是说
规定参数是 in 或 super 时,只能传这个类的 List 本身或者其父类的 List;
* 规定参数是 out 或 extends 时,只能传这个类的 List 本身或者其子类的 List。
为什么要这么规定?
来个高大上的:
Type covariance:
This means that the container types have the same relationship to each other as the payload types do. This is expressed using the extends keyword.
Type contravariance:
This means that the container types have the inverse relationship to each other as the payload types. This is expressed using the super keyword.
我看完也一头雾水。我粗暴的意译下就是 covariance(协变)是说容器的类型是可以被荷载的参数的类型”搞”的。contravariance(逆变)是说容器的类型要”搞”荷载的参数类型的。
List extends User> 可以被所有 User 及其子类的容器 add
List super User> 可以 add 所有 User 及其子类的容器
其实就是那句著名的
Producer Extends,Consumer Super
如果你是生产者,提供数据的,被 add 的,或是别人从你这取数据的,使用 Extends,放低你的姿态,让别人能 add 到你,拿到你的数据
如果你是消费者,取数据的,要 add 别人的,取别人数据的,使用 Super,抬高位置,好能 add 到别人
in 和 out 也同理