Kotlin 中 out和in

本文探讨了Java和Kotlin中泛型的使用,包括Java的extends和super以及Kotlin的out和in。在Kotlin中,out对应Java的?extends,表示只读;in则对应?super,表示只写。通过示例代码展示了如何在Kotlin中声明和使用这些泛型约束,并解释了它们在不同场景下的行为差异。
摘要由CSDN通过智能技术生成

关于java中泛型的上下限和读取模式先看这篇文章
Java中泛型上下限及读写模式

对java中有一定的了解后,再来看kotlin中与之对应的定义

作用Javakotlin
可读不可写extendsout
可写不可读superin

代码中实现如下,注释写的很清楚,不支持的都注释了,可以自己敲一敲感受一下


/**
 * kotlin 中 用out 和in 分别对应 ? extends 和 ? super
 * out === ? extends  可读不可写
 * in === ? super  // 可写不可读
 */

open class FatherClass {}

class ChildClass : FatherClass() {}

fun test() {
    // 为什么kt中可以直接这样写?因为在kotlin的List中,已经声明了<out E>
    // public interface List<out E> : Collection<E> {
    var list: List<FatherClass> = ArrayList<ChildClass>()
    val f: FatherClass = list.get(0);
//    val c: ChildClass = list.get(0);
//    list.add() 没有add 要用MutableList才有add

//  MutableList是对List的封装
    var list1: MutableList<out FatherClass> = ArrayList<ChildClass>()
    val f1 = list1.get(0)
    // 可读不可写
//    list1.add(FatherClass())// 报错
//    list1.add(ChildClass())// 报错

    var list2: MutableList<in ChildClass> = ArrayList<FatherClass>()
//    val c : ChildClass = list2.get(0) // 报错,可写不可读
    list2.add(ChildClass())
//    list2.add(FatherClass())// 报错
}

// kotlin中,可以直接在类中进行限制,在当前类中,T只能写,不能读
abstract class GenericKT<in T> {
    fun addData(data: T) {

    }

    // 不能读
//    abstract fun getData(): T
}

// 只能读不能修改
class OutTest<out T> {
    fun getData(): T? = null
    //报错 不能写
//    fun setData(data: T){}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Kotlin语言,`in`和`out`关键字用于泛型类型的声明,用于表示逆变和协变。 - `in`关键字表示逆变,用于限制泛型类型的下界。逆变意味着只能将泛型类型作为消费者使用,即只能从读取数据,而不能修改或写入数据。逆变可以确保类型的安全性。在Kotlin,`in`关键字可以用于函数参数、属性和类型别名的声明。 - `out`关键字表示协变,用于限制泛型类型的上界。协变意味着可以将泛型类型作为生产者使用,即可以从读取数据,并且可以将其作为返回值返回。协变可以确保类型的安全性。在Kotlin,`out`关键字可以用于函数返回类型、属性和类型别名的声明。 下面是一个示例,演示了Kotlin的`in`和`out`的使用: ```kotlin // 定义一个接口 interface Animal { fun sound() } // 定义一个类实现Animal接口 class Dog : Animal { override fun sound() { println("Woof!") } } // 定义一个类实现Animal接口 class Cat : Animal { override fun sound() { println("Meow!") } } // 定义一个函数,使用in关键字限制泛型类型的下界 fun <T : Animal> makeSound(animals: List<in T>) { for (animal in animals) { animal.sound() } } // 定义一个函数,使用out关键字限制泛型类型的上界 fun <T : Animal> getAnimalSounds(animal: T): List<out T> { return listOf(animal) } // 创建Dog和Cat对象 val dog = Dog() val cat = Cat() // 调用makeSound函数,传入Dog和Cat对象的列表 makeSound(listOf(dog, cat)) // 调用getAnimalSounds函数,获取Dog和Cat对象的声音列表 val sounds = getAnimalSounds(dog) for (sound in sounds) { sound.sound() } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值