在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.foo
和D.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上的实例