我想知道为什么泛型父类(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>类型。

但是,PetCat的父类(super class)型。为什么多态不能像下面这样工作?
open class SuperClassName() {}

class SubClassName : SuperClassName()

var variableName: SuperClassName = SubClassName()

最佳答案

PetCat的父类(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,意思是“如果AB的子类型,那么Retailer<A>Retailer<B>的子类型。
  • 10-07 15:45