Android 协变和逆变

Android 协变和逆变

  • Dog 是 Animal 的子类
  • 型变分为:Invariant 抗变(不变)、Covariance 协变和 Contravariance 逆变
  • 抗变:List<Dog>List<Animal> 没有任何继承关系,直接赋值会编译报错,所以抗变严重制约了程序的灵活性
  • 协变:List<Dog>List<Animal> 的子类型,即子类型可以赋值给父类型
  • 逆变: List<Animal>List<Dog> 的子类型,即父类型可以赋值给子类型

协变

  • 适用于 Producer 生产者角色的泛型类或接口,只能读取数据,不能写入
  • 类中不能有接受该类型参数作为方法参数的成员,只能返回该类型
  • Java 的 List<? extends Animal> 对应 Kotlin 的 List<out Animal>
java 复制代码
public void getOutAnimal(List<? extends Animal> list) {
    for (Animal animal : list) { 
        //读取数据
    }
}
kotlin 复制代码
//Producer<String> 可以赋值给 Producer<Any>
interface Producer<out T> {
    fun produce(): T  //只能返回 T,不能接受 T 作为参数
}

逆变

  • 适用于 Consumer 消费者角色的泛型类或接口,只能写入数据,不能读取
  • 类中不能有返回该类型参数的成员,只能接受该类型作为参数
  • Java 的 List<? super Dog> 对应 Kotlin 的 List<in Dog>
java 复制代码
public void putAnimalIn(List<? super Dog> list) {
    //写入数据
    list.add(new Dog()); //可以安全写入 Dog 或其子类
}
kotlin 复制代码
//Consumer<String> 可以赋值给 Consumer<Any>
interface Consumer<in T> {
    fun consume(value: T)  //只能接受 T,不能返回 T
}

总结

  • 协变:在 Java 中使用 ? extends E 表示,在 Kotlin 中使用 out E 表示,表示上界为 E
  • 逆变:在 Java 中使用 ? super E 表示,而在 Kotlin 中使用 in E 表示,表示下界为 E
  • PECS 原则:Producer-Extends,Consumer-Super
  • Producer -> output -> out
  • Consumer -> input -> in
相关推荐
奥尔特星云大使7 小时前
MySQL 慢查询日志slow query log
android·数据库·mysql·adb·慢日志·slow query log
2501_9159184111 小时前
iOS 框架全解析,原生框架与跨平台框架对比、开发应用打包与 App Store 上架实战经验
android·ios·小程序·https·uni-app·iphone·webview
K24B;11 小时前
多模态大语言模型LISA++
android·人工智能·语言模型·分割·多模态大语言模型
molihuan17 小时前
开源 全平台 哔哩哔哩缓存视频合并 Github地址:https://github.com/molihuan/hlbmerge_flutter
android·flutter·缓存·ffmpeg·开源·github·音视频
奶糖 肥晨17 小时前
批量重命名技巧:使用PowerShell一键整理图片文件命名规范
android·服务器·数据库
Momentary_SixthSense18 小时前
如何对较长的Stream链进行Debug
android·java·开发语言
little_fat_sheep18 小时前
【Rive】rive-android源码分析
android
教程分享大师20 小时前
新魔百和m401h全部版本当贝桌面固件卡刷包和线刷包带adb权限
android
rufeii20 小时前
网鼎杯 2020 青龙组
android
我要升天!21 小时前
MySQL表的内连和外连
android·mysql·adb