Kotlin-泛型和委托

2021-03-22  本文已影响0人  在下陈小村
泛型

泛型的使用是为了程序有更好的扩展性。
泛型类和泛型方法

class MyClass<T> {
    fun <T>method(param:T):T{
        return param
    }
}

泛型的高级特性
java的泛型是通过类型擦除机制来实现的,什么事类型擦除机制,就是说泛型对于类型的约束只在编译时期存在,运行时,JVM是识别不了我们在代码中指定的泛型类型的。

泛型实化
Kotlin也是基于JVM上的语言,所以同样存在类型擦除机制。但是Kotlin中有一个内联函数,这个是用代码替换的方式的原理实现的,所以避免了类型擦除机制,从而可以通过T::class.java来知道泛型是具体什么类型的。这里有个泛型实化必须添加的关键字reified

inline fun <reified T> getGenericType()=T::class.java

fun main(){
    val result1= getGenericType<String>()
    val result2= getGenericType<Int>()
    println(result1)
    println(result2)
}

泛型实化的应用

 inline fun <reified T>startActivity(context: Context){
        val intent=Intent(context,T::class.java)
        context.startActivity(intent)
    }
    inline fun <reified T>startActivity(context: Context,block:Intent.()->Unit){
        val intent=Intent(context,T::class.java)
        intent.block()
        context.startActivity(intent)
    }

       startActivity<TestActivity>(this)
        startActivity<TestActivity>(this){
            putExtra("param1","1")
            putExtra("param2","2")
        }

泛型的协变
官方一点的描述,A是B的子类型,MyClass<A>又是MyClass<B>的子类型。那么我们就可以称MyClass在T这个泛型上是协变的。
通俗的话来说MyClass中的数据是只读就可以避免类型转换异常,比如下面这个方法,只有get方法,并且只能通过构造函数来设置初始化值。注意关键字out

class SimpleData<out T>(val data:T){
    fun get():T{
        return data
    }
}

协变在kotlin中的应用就是List

泛型的逆变
官方描述:A是B的子类型,MyClass<B>又是MyClass<A>的子类型,那么我们称MyClass在T这个泛型上是逆变的
用通俗的话来说A里面的属性就是B里面的属性,规定了不会类型转换异常,注意关键字in这个和协变是相反的。

interface Transformer<in T>{
    fun transform(t:T):String
}
委托

类委托
简单来说就是自己写的类,里面的一些方法在别的类已经有现成的写好了,直接用他的方法就可以了。和继承还有点点区别,委托只是取自己想要的方法就可以了。

class Myset<T>(val hashSet: HashSet<T>):Set<T>{
    override val size: Int
        get() = hashSet.size

    override fun contains(element: T): Boolean {
        return hashSet.contains(element)
    }

    override fun containsAll(elements: Collection<T>): Boolean {
        return hashSet.containsAll(elements)
    }

    override fun isEmpty(): Boolean {
        return hashSet.isEmpty()
    }

    override fun iterator(): Iterator<T> {
        return hashSet.iterator()
    }
}

这就是把MySet的实现方法交给了HashSet的对象来实现了,自己没有具体的实现方法,这个就是委托。
优化,每次都要写这种格式化的转接方法比较麻烦,kotlin提供了by关键字。具体实现如下,这就代表了上面这段代码。

class MySet2<T>(val hashSet: HashSet<T>):Set<T>by hashSet

属性委托
lazy函数

上一篇下一篇

猜你喜欢

热点阅读