为何Kotlin中val属性无法覆盖var属性,反之却可以正常生效?
Kotlin属性覆盖规则的设计逻辑
Kotlin的这套覆盖规则本质是严格遵循里氏替换原则设计的,同时和Java的方法覆盖规则完全对齐,核心逻辑可以拆解为两部分理解:
为什么val不能覆盖var
Kotlin的属性本质是方法的语法糖:var属性对外同时承诺了「可读」和「可写」两个能力,对应公开的getter和setter两个方法。
如果允许用val覆盖var,相当于子类直接删掉了父类已经公开承诺的setter方法,当你用父类类型引用指向子类实例时,调用父类定义的setter就会出现无实现的问题,完全违反了「所有父类可出现的场景都可以替换为子类实例」的里氏替换原则,因此编译器直接抛出Val-property cannot override var-property错误。
为什么var可以覆盖val
val属性对外仅承诺了「可读」的能力,只对应公开的getter方法。
用var覆盖val相当于子类在完整保留父类所有公开承诺的前提下,额外新增了「可写」的能力,完全不会破坏父类原有能力的可用性,所有父类可以运行的场景,替换成子类实例都可以正常执行,因此编译器允许这种操作。
内容的提问来源于stack exchange,提问作者Ji Sungbin
相关产品推荐
相关产品推荐

