在Kotlin中泛型的子类型问题

我在我的代码中有以下继承模式。

trait A { fun foo(): Set<A> } trait B : A { override fun foo(): MutableSet<B> } trait C : A { override fun foo(): Set<C> } trait D : C, B { override fun foo(): MutableSet<D> } 

当B和D返回集合时,编译器能够确定Set<D>Set<B>Set<C>的子类型。 但是,当我将B.fooD.foo的返回类型更改为MutableSet ,编译器能够验证B.foo的返回类型,但是我得到一个错误,报告D.foo的返回类型不是子类型的MutableSet<B>

为什么科特林无法推断这种形式的亚型,有没有工作,而没有检修我的等级?

重写函数的返回类型必须是重写函数的子类型。 在你的例子中, MutableSet<D>不是MutableSet<B>的子类型。 如果是这样,类似的代码可能在运行时导致异常:

 trait B { fun foo(): MutableSet<B> } trait D : B { override fun foo(): MutableSet<D> fun onlyInD() {} } class BImpl : B { override fun foo() = null!! } class DImpl : D { private val set = java.util.HashSet<D>() override fun foo() = set } fun main(args: Array<String>) { val impl = DImpl() // two variables pointing to the same instance val b: B = impl val d: D = impl b.foo().add(BImpl()) // ClassCastException on the next line: BImpl is not an instance of D d.foo().first().onlyInD() } 

请参阅try.kotl.in上的实例