Kotlin 的通用类型

Generic type of Kotlin

'''

class Cage<T: Animal>(var animal: T)

class CovariantCage<in T: Animal>(private var t: T?){
    fun getId(): Int? = t?.id
    fun getName(): String?= t?.name
    fun getContentType(t: T?){ println(t?.id)}
    fun printAnimalInfo() : String = "Animal ${t?.id} is called ${t?.name}"
}

//_______________________________________________________________________________________________

class Cage2(var animal: Animal)

class CovariantCage2(private var t: Animal?){
    fun getId(): Int? = t?.id
    fun getName(): String?= t?.name
    fun getContentType(t: Animal?){ println(t?.id)}
    fun printAnimalInfo() : String = "Animal ${t?.id} is called ${t?.name}"
}

'''

我的动物classes

'''

open class Animal(open val id:Int, open val name: String)

data class Dog(override val id: Int, override val name: String) : Animal(id, name)

data class Cat(override val id: Int, override val name: String) : Animal(id, name)

'''

  1. Cage<T> 对比 Cage2: 如果你想要功能有效,例如,特别是猫,你需要 Cage<Cat>,因为 Cage2 可以包含 Animal 的任何子类的实例。
  2. CovariantCage<T> vs CovariantCage2:它们实际上应该称为逆变笼,因为 in 使类型参数逆变,这意味着它恢复子类型关系,例如,如果 A2A1 的子类型,那么 ContravariantCage<A1>ContravariantCage<A2> 的子类型。在你的情况下,ContravariantCage<T> 是可以处理(消耗)T 类型动物的东西,但不能 return(生产)T 类型动物,所以如果你有功能,例如,接受带猫的笼子,它也应该接受带动物的笼子,因为你可以用动物做的任何事情,你也可以用猫做:
fun foo(catCage: ContravariantCage<Cat>) = ...
val animalCage: ContravariantCage<Animal> = ...
foo(animalCage)

ContravariantCage<in T : Animal> 正是这样说的。另一方面,ContravariantCage2 根本没有类型差异,因为它没有类型参数。