我想知道为什么泛型父类(super class)型参数不允许引用子类型对象的背景。
abstract class Pet()
class Cat: Pet()
interface Retailer<T> {
fun sell(): T
}
class CatRetailer: Retailer<Cat> {
override fun sell(): Cat {
println("Sell Cat")
return Cat()
}
}
// Type MismatchError prior to compilation
val steveIrwinTheAnimalEnslaver: Retailer<Pet> = CatRetailer()
变量定义会导致类型不匹配错误,其中编译器需要
Retailer<Pet>
类型。但是,
Pet
是Cat
的父类(super class)型。为什么多态不能像下面这样工作?open class SuperClassName() {}
class SubClassName : SuperClassName()
var variableName: SuperClassName = SubClassName()
最佳答案
Pet
是Cat
的父类(super class)型,但是Retailer<Pet>
不是Retailer<Cat>
的父类(super class)型。看看为什么想象您添加了一个方法:
abstract class Pet()
class Cat: Pet()
class Dog: Pet()
interface Retailer<T> {
fun sell(): T
fun buy(x: T): Unit
}
// only really knows how to buy cats
val steveIrwinTheAnimalEnslaver: Retailer<Pet> = CatRetailer()
// legal for any Retailer<Pet>
steveIrwinTheAnimalEnslaver.buy(Dog())
在这种情况下,您可以选择:
Retailer<out Pet>
,它不允许像buy
这样的调用成员“消耗” T
。您可以将其视为Retailer<any subtype of Pet>
,并且不会有太大错误。还有双重Retailer<in Pet>
,它允许调用buy
,但不能调用sell
。 interface Retailer<out T>
,它不允许声明buy
,意思是“如果A
是B
的子类型,那么Retailer<A>
是Retailer<B>
的子类型。