为什么通用超类型声明不允许引用子类型对象?

Why Does a Generic Supertype Declaration Not Permit Referencing to Subtype Objects?

我想知道为什么泛型超类型参数不允许引用子类型对象的背景。

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>

但是,PetCat 的超类型。为什么多态性不像下面那样工作?

open class SuperClassName() {}

class SubClassName : SuperClassName()

var variableName: SuperClassName = SubClassName()

您写道: class CatRetailer: Retailer<Cat> 为了使代码工作,您需要编写: class CatRetailer: Retailer<Pet>

猫零售商没有实现宠物的接口,它实现了猫的接口。如果它会实现 pet 的接口,你可以这样写: val steveIrwinTheAnimalEnslaver: Retailer<Pet>

在实现 cat 的接口时,您是在说您的零售商是 cat 类型并且只有 cat。

Cat 类型的接口 没有 extend/implement Pet 类型的接口。

您给出的子类化示例不是这种情况。

总结一下:即使 B 扩展了 A,Interface<B> 也不是 interface<A>。 但是B就是A。

我希望你已经足够清楚了。

PetCat 的超类型,但 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())

在这种情况下,您的选择是:

  1. 使用 Retailer<out Pet>,它不允许调用像 buy 和 "consume" T 这样的成员。你可以把它想象成Retailer<any subtype of Pet>,你不会错的。还有双重 Retailer<in Pet> 允许调用 buy 但不允许调用 sell.

  2. Declare interface Retailer<out T> 不允许 declaring buy 并且意味着“如果 A 是 [=25 的子类型=],则 Retailer<A>Retailer<B> 的子类型。