泛型类
泛型类的构造参数可以是任何类型,一般用 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
提升扩展性。
- out
协变,只能用作输出 - 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("宝马")
}
}