Kotlin 覆盖超类型变量

Voj*_*ěch 6 kotlin

考虑两个类:

abstract class ParentRepository {}

class ChildRepository : ParentRepository {}

abstract class ParentClass {
    protected abstract var repository: ParentRepository
}

class ChildClass : ParentClass {
    override var repository: ChildRepository
}
Run Code Online (Sandbox Code Playgroud)

最后一部分不起作用:

override var repository: ChildRepository
Run Code Online (Sandbox Code Playgroud)

它会抱怨:

Type of 'repository' doesn't match the type of the overridden var-property 'protected abstract var repository: ParentRepository
Run Code Online (Sandbox Code Playgroud)

我理解这个问题,但我不明白为什么这不应该起作用 - ChildRepository 是 ParentRepository 的一个实例,这是我在 Java 中习惯的常见事物。

dip*_*dip 9

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

protected abstract val repository: ParentRepository

override var repository: ChildRepository
Run Code Online (Sandbox Code Playgroud)


tyn*_*ynn 6

您必须考虑到Kotlin 中的属性是一组 getter 和 setter。虽然 aval只有一个 getter,但 avar还定义了一个 setter。因此,您可以设置repository一个ParentRepository可能不是ChildRepository.

如果您考虑泛型的差异,您将看到相同的行为。虽然您可以对 getter使用协方差 <out T>,但您必须对 setter使用逆变 <in T>