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)
'''
- 我什么时候应该使用通用 class?
Cage<T>
对比 Cage2
:
如果你想要功能有效,例如,特别是猫,你需要 Cage<Cat>
,因为 Cage2
可以包含 Animal 的任何子类的实例。
CovariantCage<T>
vs CovariantCage2
:它们实际上应该称为逆变笼,因为 in
使类型参数逆变,这意味着它恢复子类型关系,例如,如果 A2
是 A1
的子类型,那么 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
根本没有类型差异,因为它没有类型参数。
- 这两个代码有什么区别?
'''
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)
'''
- 我什么时候应该使用通用 class?
Cage<T>
对比Cage2
: 如果你想要功能有效,例如,特别是猫,你需要Cage<Cat>
,因为Cage2
可以包含 Animal 的任何子类的实例。CovariantCage<T>
vsCovariantCage2
:它们实际上应该称为逆变笼,因为in
使类型参数逆变,这意味着它恢复子类型关系,例如,如果A2
是A1
的子类型,那么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
根本没有类型差异,因为它没有类型参数。