当前位置: 首页 > news >正文

Kotlin协变与逆变区别

在Kotlin中,协变和逆变是泛型编程中的两个重要概念,它们允许我们在类型系统中更加灵活地处理类型关系。
1.协变:协变允许我们使用比原始类型更具体的类型。在kotlin中,通过在类型参数上加out关键字来表示协变,生产者,例如,如果我们有一个泛型类List,其中T是一个协变类型参数,那么我们可以将List赋值给List,因为String是Any的子类型。

2.逆变:逆变允许我们使用比原始类型更一般的类型。在kotlin中,通过在类型参数上加in关键字来表示逆变,消费者,例如,如果我们有一个泛型函数fun foo(list: List),其中T是一个逆变类型参数,那么我们可以将List传递给foo函数,因为Any是String的超类型。

协变代码举例:

interface Producer<out T> {//协变 out 类似java中的 extend
  fun produce(): T
}
open class Fruit
open class Apple: Fruit()


class FruitProducer:Producer<Fruit> {
    override fun produce(): Fruit {
       return Fruit()
    }
}

class AppleProducer:Producer<Apple> {
    override fun produce(): Apple {
        return Apple()
    }
}

fun <T> processProduce(producer:Producer<T>) {
    val product = producer.produce()
    println(product)
}

fun main(){
    var fruitProducer:Producer<Fruit> = FruitProducer()
    var appleProducer:Producer<Apple> = AppleProducer()
    processProduce(fruitProducer)
    processProduce(appleProducer)
//    appleProducer = fruitProducer  //报错,协变,不允许将Producer<Fruit>赋值给Producer<Apple>
//    fruitProducer = appleProducer //协变,允许将Producer<Apple>赋值给Producer<Fruit>

}

逆变代码举例:

interface Consumer<in T>{ //逆变 in 类似java中的super
    fun consume()
}

class FruitConsumer:Consumer<Fruit>{
    override fun consume() {
        println("consume fruit")
    }
}

class AppleConsumer:Consumer<Apple>{
    override fun consume() {
        println("consume apple")
    }
}

inline fun <T> processConsumer(consumer:Consumer<T>){
    consumer.consume()
}


fun main() {
    var fruitConsumer:Consumer<Fruit> = FruitConsumer()
    var appleConsumer:Consumer<Apple> = AppleConsumer()
    processConsumer(fruitConsumer)
    processConsumer(appleConsumer)
//    fruitConsumer = appleConsumer //报错,逆变,不允许将Consumer<Apple>赋值给Consumer<Fruit>
//    appleConsumer = fruitConsumer  //允许将Consumer<Fruit>赋值给Consumer<Apple>,

}

相关文章:

  • 网络安全完成mysql加固
  • [Web 安全] PHP 反序列化漏洞 —— POP 链构造思路
  • YOLOv11-ultralytics-8.3.67部分代码阅读笔记-VOC.yaml
  • 目录遍历文件包含测试
  • 精品整理-2025 DeepSeek核心技术解析与实践资料合集(24份)
  • 类中的流操作符的重载
  • Python 数据可视化(一)熟悉Matplotlib
  • python判断、循环、range语句
  • Servlet简介
  • 2025最新Nginx高频面试题
  • Python的pdf2image库将PDF文件转换为PNG图片
  • windous 下 ollama 迁移到 D 盘
  • 【2025年2月28日稳定版】小米路由器4C刷机Immortalwrt 23.05.4系统搭载mentohust 0.3.1插件全记录
  • 【Mark】记录用宝塔+Nginx+worldpress+域名遇到的跨域,301,127.0.0.1,CSS加载失败问题
  • 如何流畅访问github
  • 架构案例:从初创互联网公司到分布式存储与反应式编程框架的架构设计
  • 2011-2019年各省移动电话普及率数据
  • Deepseek对ChatGPT的冲击?
  • (平衡二叉树 判断是否为AVL树 )leetcode110
  • Python 模块与包:从零到自定义的全面指南
  • 东莞做网站定制/百度怎么推广
  • 营销型网站建设企业/引擎网站推广法
  • 想让网站的文章都被收录怎么做/深圳搜索引擎优化推广便宜
  • c语言网站/湖南网站制作公司
  • wordpress建站 百度网盘/百度快照关键词推广
  • 阿里云的网站建设方案/郑州网络推广专业公司