我想知道为什么泛型超类型参数不允许引用子类型对象的背景。
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
的超类型。为什么多态性不能像下面那样工作?
open class SuperClassName() {}
class SubClassName : SuperClassName()
var variableName: SuperClassName = SubClassName()
答案 0 :(得分:1)
您写道:
class CatRetailer: Retailer<Cat>
为了使代码正常工作,您需要编写:
class CatRetailer: Retailer<Pet>
Cat零售商没有实现pet的接口,而是实现了cat的接口。如果它将实现pet的接口,则可以编写:
val steveIrwinTheAnimalEnslaver: Retailer<Pet>
在实现 cat 的界面时,您是说零售商的类型为 cat ,并且仅是cat。
Cat类型的接口不扩展/实现Pet类型的接口。
这不是您通过子类给出的示例的情况。
总结:即使B扩展了A,Interface<B>
也不是interface<A>
。
但是B是A。
我希望足够清楚。
答案 1 :(得分:1)
Pet
是Cat
的超类型,但是Retailer<Pet>
并非Retailer<Cat>
的超类型。看看为什么想象您添加了一个方法:
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
的子类型,则{{1 }}是Retailer<A>
的子类型。