Inheritance 无法使用子接口重写Kotlin属性

Inheritance 无法使用子接口重写Kotlin属性,inheritance,interface,kotlin,Inheritance,Interface,Kotlin,在下面的简化示例中,您能否解释为什么Kotlin编译器在重写a时抱怨我们进一步限制了它的类型(编译器消息:Var属性类型为“B”,它不是被重写的公共抽象变量a:a的类型) 此外,编译器不会抱怨以下代码段: open class G class H : G() abstract class F { abstract val g: G } class I : F() { override var g : H = H() } 因此,我猜接口继承中存在一些问题,而类中没有这种问题

在下面的简化示例中,您能否解释为什么Kotlin编译器在重写a时抱怨我们进一步限制了它的类型(编译器消息:
Var属性类型为“B”,它不是被重写的公共抽象变量a:a的类型

此外,编译器不会抱怨以下代码段:

open class G

class H : G()

abstract class F {
    abstract val g: G
}

class I : F() {
    override var g : H = H()
}

因此,我猜接口继承中存在一些问题,而类中没有这种问题。

您的第一个代码段无法编译,否则可能会出现这种奇怪的情况:

val d: D = E()
d.a = object : A {}  // Some other sub-type of A, but definitely not a sub-type of B
这实际上是的一个变体(不是双关语),特别是考虑到Kotlin
var
属性实际上只是getter和setter方法的语法糖


相反,您的第二个代码段确实可以编译,因为在本例中,协方差不是问题-基类(
F
)中没有要重写的setter,所以我上面描述的“古怪”是不可能的。

@SimonMarynissen-这里的问题实际上是可变性(即,您可以通过基类引用设置属性的事实)。因此,一种解决方案是将其设置为
val
属性。但我认为另一种解决方法是使用泛型,即
抽象类D{abstract var a:T}
类e:D(){override var a:B=C}
。但这并不适用于所有情况。
val d: D = E()
d.a = object : A {}  // Some other sub-type of A, but definitely not a sub-type of B