Kotlin重写超类型变量

时间:2018-02-23 11:02:37

标签: kotlin

考虑两个类:

abstract class ParentRepository {}

class ChildRepository : ParentRepository {}

abstract class ParentClass {
    protected abstract var repository: ParentRepository
}

class ChildClass : ParentClass {
    override var repository: ChildRepository
}

最后一部分不起作用:

override var repository: ChildRepository

它会抱怨:

Type of 'repository' doesn't match the type of the overridden var-property 'protected abstract var repository: ParentRepository

我理解这个问题,但是我不知道为什么这不应该工作 - ChildRepository是一个ParentRepository的实例,这是我习惯用Java的常见事情。

3 个答案:

答案 0 :(得分:3)

您必须将repository声明为val。您仍然可以将其覆盖为var:

protected abstract val repository: ParentRepository

override var repository: ChildRepository

答案 1 :(得分:2)

您必须考虑在 Kotlin 属性中是一组getter和setter。虽然val只有一个getter,但var也定义了一个setter。因此,您可以将repository设置为ParentRepository实例,该实例可能不是ChildRepository的实例。

如果考虑泛型的差异,您会看到相同的行为。虽然您可以将协方差 <out T>用于获取者,但您必须使用 contravariance <in T>作为设置者。

答案 2 :(得分:0)

使用关键字open

protected open var repository: ParentRepository