​安卓系列之 kotlin 基础知识(六)

122 阅读2分钟

泛型类

泛型类的构造参数可以是任何类型,一般用 T(type)表示。

//泛型类
class Box<T>(content: T) {

}

class Water {

}

fun testBox() {
    //T类型为字符串
    val can1 = Box("字符串")
    //T类型为Water对象
    val can2 = Box(Water())
    //T类型为整型
    val can3 = Box(1)
}

泛型函数

泛型函数的传入类型或者返回类型为 T

//泛型函数
fun <T> getType(content: T): String {
    return when (content) {
        is Number -> "是数字"
        is String -> "是字符串"
        is Boolean -> "是波尔值"
        else -> "未知类型"
    }
}

class Phone(val name: String, val type: String) {

}

fun testGetType() {
    getType(Phone("华为手机""鸿蒙系统"))
    getType("测试测试")
    getType(10086)
}

class ApplePhone<T>(content: T) {
    private var phone = content
    fun getInstance(): T? {
        return phone
    }

    //通过传入泛型转换成其他泛型
    fun <R> getPhone13(function: (T) -> R): R? {
        return function(phone)
    }
}

泛型类型约束

约束 T 的类型,只有继承了该类型的类传入方法才可以使用,多个约束条件可以使用 where 关键字

//父类
open class Animal(var foot: Int)

//鸭子,继承Animal
class Duck(var eat: String) : Animal(foot = 2)

//兔子,继承Animal
class Rabbit(var eat: String) : Animal(foot = 4)

open class Furniture(var type: String)

//桌子,没有继承Animal
class Desk(var size: Int) : Furniture("桌子")

//T类型的约束条件是Animal
fun <T : Animal> showAnimalFoot(param: T) {
    print(param.foot)
}

fun testAnimal() {
    showAnimalFoot(Duck("米"))
    showAnimalFoot(Rabbit("胡萝卜"))
    //showAnimal(Desk(2))//报错,原因是Desk不属于Animal
}

//多个约束条件
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
        where T : CharSequence,
              T : Comparable<T> {
    return list.filter { it > threshold }.map { it.toString() }
}

多个泛型参数

vararg,可以传入多个参数 相当于是 Java 的...

//vararg,可以传入多个参数 相当于是Java的...
fun <T> getFlower(vararg flower: T) {
    val flowerArray: Array<out T> = flower
}

fun testGetFlower() {
    getFlower("a",1)
}

out 和 in

提升扩展性。

  1. out
    协变,只能用作输出
  2. in
    逆变,只能用作输入
//生产者
interface Production<out T> {
    fun product(): T
}

//消费者
interface Consumer<in T> {
    fun consume(item: T)
}

open class Food
open class FastFood : Food()
class Burger : FastFood()

class FoodStore : Production<Food> {
    override fun product(): Food {
        return Food()
    }
}

class FastFoodStore : Production<FastFood> {
    override fun product(): FastFood {
        return FastFood()
    }
}

class BurgerStore : Production<Burger> {
    override fun product(): Burger {
        return Burger()
    }
}

class Everyone : Consumer<Food> {
    override fun consume(item: Food) {
        print("eat food")
    }
}

class ModernPeople : Consumer<FastFood> {
    override fun consume(item: FastFood) {
        print("eat FastFood")
    }
}

class American : Consumer<Burger> {
    override fun consume(item: Burger) {
        print("eat Burger")
    }
}


fun testInOut() {
    //子类泛型对象可以赋值给父类泛型对象,用out
    val prduction1: Production<Food> = FoodStore()
    val prduction2: Production<Food> = FastFoodStore()
    val prduction3: Production<Food> = BurgerStore()
    //父类泛型对象可以赋值给子类泛型对象,用in
    val consumer1: Consumer<Food> = Everyone()
    val consumer2: Consumer<FastFood> = ModernPeople()
    val consumer3: Consumer<Burger> = American()
}

inline 和 reified

reified 关键字可以检查泛型参数类型。

open class Transportation(val energy: String)

class ElectricityCar(val name: String) : Transportation("电")

class OilCar(val name: String) : Transportation("油")

class TransportationFactory {
    //根据传入的类型推导出T的类型,从而可以进行T的判断
    inline fun <reified T> getTransportation(transportation: () -> T): T {
        val list = listOf(ElectricityCar("比亚迪"), OilCar("奔驰"))
        val random = list.shuffled().first()
        return if (random is T) {
            random
        } else {
            transportation()
        }
    }
}

fun testTransportationFactory() {
    val factory = TransportationFactory()
    //此处的result类型为OilCar
    val result = factory.getTransportation {
        OilCar("宝马")
    }
    //此处的result类型为ElectricityCar
    val result2 = factory.getTransportation {
        ElectricityCar("宝马")
    }
}

项目 github 地址

github.com/ElaineTaylo…

若帅哥美女对该系列文章感兴趣,可微信搜索公众号(木子闲集)关注更多更新文章哦,谢谢~