kotlin: 泛型: 用in实现逆变

一,功能

逆变是指在类型参数的继承关系中,允许将一个泛型类型的父类型赋值给子类型。
在 Kotlin 中,我们可以使用
in 关键字来标记类型参数为逆变。
这样一来,我们就可以安全地将一个泛型类型的父类型赋值给子类型。

二,例子:

逆变关键字 in 将继承关系颠倒过来,主要用来限制未知类型的子类型,
编译器知道子类型是 Number,因此只要是 Number 的父类都可以添加。

因为 numbers.get(0) 获取的的值是 Any? 的类型,因此它不能直接赋值给 int 类型,
逆变和协变一样,放宽了对数据类型的约束,但是代价是 不能按照泛型类型读取元素
也就是说往集合中添加 int 类型的数据,调用 get() 方法获取到的不是 int 类型的数据

代码:

        //处理按钮点击事件
        binding.button1.setOnClickListener {
            val numbers1: MutableList<in Number> = ArrayList<Number>()
            numbers1.add(100)
            val f1 = numbers1.get(0)
            println("第一个元素:"+f1)

            val numbers2: MutableList<in Int> = ArrayList<Number>()
            numbers2.add(100)
            val f2 = numbers2.get(0)
            println("第一个元素:"+f2)  // Any?
            println("第一个元素的类型:"+f2!!::class.simpleName)
            println("第一个元素的类型:"+f2::class.java)
            //val f4:Int = numbers2.get(0) // 报错
            val f4: Int = numbers2.get(0) as? Int ?: 0
            println("第一个元素的整数类型:"+f4)
        }

运行结果:

image

三,例子:

代码:

interface Processor<in T> {
    fun process(item: T)
}

调用:

        //处理按钮点击事件
        binding.button2.setOnClickListener {
            open class Animal {
                open fun info() {
                    println("当前类:Animal")
                }
            }
            class Cat : Animal() {
                override fun info() {
                    println("当前类:Cat")
                }
            }

            val animalProcessor: Processor<Animal> = object : Processor<Animal> {
                override fun process(item: Animal) {
                    println("Processing animal: $item")
                    println("item的类型:"+item::class.simpleName)
                    item.info()
                }
            }

            val catProcessor: Processor<Cat> = animalProcessor // 逆变
            catProcessor.process(Cat())
            //catProcessor.process(Animal())
        }

运行结果:

image

四,例子:

代码:

interface Product2<in T>{
    fun setProduct2(item:T){
    }
}

调用:

        //处理按钮点击事件:
        binding.button3.setOnClickListener {
            open class People() {
                open fun show() {
                    println("people")
                }
            }

            class Man() : People() {
                override fun show() {
                    println("男人")
                }
            }

            class Woman() : People() {
                override fun show() {
                    println("女人")
                }
            }


            class Product2One:Product2<People>{
                override fun setProduct2(item: People) {
                    item.show()
                }
            }


            //in:泛型具体处的父类对象 可以赋值给 泛型声明处的子类对象
            var people:Product2<Woman> = Product2One()
            people.setProduct2(Woman())

            var people2:Product2<Man> = Product2One()
            people2.setProduct2(Man())
        }

运行结果:

image

posted @ 2025-09-06 08:37  刘宏缔的架构森林  阅读(15)  评论(0)    收藏  举报