第8章 kotlin泛型

187 阅读2分钟

8.1、泛型的基本概念

函数申明泛型

inline fun <T> maxOf(a: T, b: T): T{    }

类申明泛型

class MyTest<T> {
    
}

8.2、泛型的约束

1、添加类型约束

要求T可以比较大小

    inline fun <T : Comparable<T>> maxOf(a: T, b: T): T {
        return if (a > b) a else b
    }

2、添加多个类型约束

进一步:要求T可以比较大小同时是一个函数

    inline fun <T> callMax(a: T, b: T)
            where T : Comparable<T>, T : () -> Unit {
        return if (a > b) a() else b()
    }

3、多个泛型参数

    inline fun <T, R> callMax(a: T, b: T): R
            where T : Comparable<T>, T : () -> R, R : Number {
        return if (a > b) a() else b()
    }

多个泛型参数的例子

K是Serializable类型,V是Comparable类型

class Map<K,V> where K:Serializable,V:Comparable<V>

8.3、泛型的型变

定义

例子1

首先看一个泛型的例子

class MainActivity2 : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        var array1: Array<B> = arrayOf(B(), B(), B())
        val array2: Array<A> = array1

    }


}

open class A

class B : A()

发现发现 val array2: Array = array1会有提示错误 Type mismatch. Required:Array Found:Array,Array并不是Array的子类,因为kotlin中的泛型默认是不型变的,无法完成类型转换,但是B是A的子类,但是这个赋值理论上是合理的,安全的。

那么我们如何解决这个问题呢?

class MainActivity2 : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        var array1: Array<B> = arrayOf(B(), B(), B())
        val array2: Array<out A> = array1

    }


}

open class A

class B : A()

类或接口泛型参数被声明为out时,则该类型参数是协变的。

****好处是:**A****B**的父类,那么**List<A>**可以是**List<B>**的父类。***

例子2

我们看另外的一个泛型的例子

class MainActivity2 : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        var array1: Array<A> = arrayOf(A(), A(), A())
        val array2: Array<B> = array1

    }


}

open class A

class B : A()

 发现 val array2: Array = array1 会有提示错误:Type mismatch. Required: Array Found: Array ,Array 并不是Array的子类,针对这种情况,该怎么办呢?

class MainActivity2 : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        var array1: Array<A> = arrayOf(A(), A(), A())
        val array2: Array<in B> = array1

    }


}

open class A

class B : A()

类或接口泛型参数被声明为in时,则该类型参数是逆变的。

好处是:**A****B**的父类,那么**List<B>**可以是**List<A>**的父类。

逆变的理解?

比如Number是父类,Int是子类

但是Comparable 是子类,Comparable 是父类

逆变可以这么理解:他们的关系发生了转换,如果一个数是Int,那么这个数就是Number

如果可以比较Number,那么一定可以比较Int,这种关系居然发生了变化。

new