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 类似java中的 extend
  fun produce(): T
}
open class Fruit
open class Apple: Fruit()


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

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

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

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

}

逆变代码举例:

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

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

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

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


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

}

你可能感兴趣的:(kotlin,开发语言,android)