kotlin in out 关键字理解

本文通过实例代码详细解释了Kotlin中泛型接口的in和out关键字,说明了它们在类型协变和逆变中的作用。in关键字用于表示消费者接口,确保消费的对象类型必须是接口指定的类型或其子类型;out关键字用于表示生产者接口,保证返回的对象是接口指定类型或其超类型。通过示例代码展示了当违反这些约束时,编译器会报错,强调了类型安全的重要性。
摘要由CSDN通过智能技术生成

在kotlin定义范型时,有时会使用到in out关键字。网上很多文章都有介绍这两个关键字的使用,越看越迷糊,比如以下边的食物、快餐、汉堡、食物商店,快餐店、汉堡店为例子:

很不理解为什么下边的几行代码前两行会编译通过,而后一个会出错。

val consumer1: Consumer<Burger> = FoodConsumer()
val consumer2: Consumer<Burger> = FastFoodConsumer()
val consumer3: Consumer<Food> = BurgerConsumer()//compile error

以最后一行代码为例, 换一个角度想,在通过val consumer3: Consumer<Food>来声明一个变量时,就是告诉编译器后来对该变量的使用都要严格遵守他的类型约定,比如consumer3他的类型是Consumer<Food>,那么他调用consume方法时,就必须传入Food参数。而consumer3由于是饮用变量,实际传给他的对象是一个BurgerConsumer对象,该对象里边的consumer方法能接受的参数只能接收Burger类型,所以这就出现了变量的声明跟实际情况不符的情况,显然通过下边的方法调用consumer3的consume()方法会报错。依次类推,用同样方式可以解释为什么其他情况。

val food = Food()
consumer3.consume(food)

完整代码示例如下:

interface Producer<out T>{
    fun produce(): T
}

interface Consumer<in T>{
    fun consume(item: T)
}
open class Food
open class FastFood: Food()
class Burger: FastFood()

class FoodStore: Producer<Food>{
    override fun produce(): Food {
        println("Produce one food!")
        return Food()
    }
}

class FastFoodStore: Producer<FastFood>{
    override fun produce(): FastFood {
        println("produce one fastfood!!")
        return FastFood()
    }
}

class BurgerFoodStore: Producer<Burger>{
    override fun produce(): Burger {
        println("Produce one burger!!")
        return Burger()
    }
}

class FoodConsumer: Consumer<Food>{
    override fun consume(item: Food) {
        println("Consume one food!")
    }
}

class FastFoodConsumer: Consumer<FastFood>{
    override fun consume(item: FastFood) {
        println("Consume one fastfood")
    }
}

class BurgerConsumer: Consumer<Burger>{
    override fun consume(item: Burger) {
        println("Consume one burger")
    }
}

fun main(){
    val producer: Producer<Food> = FoodStore()
    val producer1: Producer<Food> = FastFoodStore()
    val producer2: Producer<Food> = BurgerFoodStore()
    val producer3: Producer<Burger> = BurgerFoodStore()
//    val producer4: Producer<Burger> = FoodStore()//compile error
//    val producer5: Producer<Burger> = FastFoodStore()//compile error

    val consumer1: Consumer<Burger> = FoodConsumer()
    val consumer2: Consumer<Burger> = FastFoodConsumer()
    val consumer3: Consumer<Food> = BurgerConsumer()//compile error
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值