接口中的属性不能有后台字段
我正在学习Kotlin 。 我的代码如下:
interface BaseLogicDecoupler<A : BaseViewNotifier, B : BaseScreenRouter> { var notifier: A? var router: B? fun attachNotifier(notifier: A?) { this.notifier = notifier } fun detachNotifier() { notifier = null; } fun attachRouter(router: B?) { this.router = router } fun detachRouter() { router = null; } }
但是,当我改变它,并尝试提供像以下属性的访问器:
var notifier: A? get() = notifier
它不会编译错误说: 接口中的属性不能有一个后台字段 。
从这里的文档,kotlin接口可以提供实现,并可以具有访问器的属性。 为什么编译失败?
我无法理解错误。 它说什么? 任何人都可以简单的解释吗?
这是一个意想不到的案例,对你的发现感到很荣幸。
让我简单地解释一下。 为简单起见,我将使用一个剥离的接口A
和B
interface A { var notifier: Int }
通常,类中的var
属性包含三个组件:一个用于存储其值的私有backing field
,一个用于写入的setter
方法以及一个用于读取它的getter
方法。 但是一个接口不能有一个字段(因为live是痛苦的,有些数学不会加起来),所以一个接口的var
属性只包含两个组件:一个setter
和一个getter
。
正如我上面所概述的,我们的接口A
已经声明了两个方法: setter
和getter
,都没有实现。 我们来添加一些实现:
interface A2 { var notifier: Int get() {return 1} set(v) {} }
到现在为止还挺好。 两个open
方法与实现,而不是他们使用任何领域。 但是如果只有一个实现被声明呢?
interface A3 { var notifier: Int //ERROR: Property in an interface cannot have a backing field get() {return 1} //set(v) {} }
事实证明,如果只指定一个getter
,Kotlin还会为该属性生成一个(默认) setter
。 换句话说, A3
在这里与A4
类似:
interface A4 { var notifier: Int get() {return 1} set(v) {field = v} //Obviously an error }
这可能是一个错误或一个预期的行为。 这是问题单: https : //youtrack.jetbrains.com/issue/KT-15193
可能的解决方法:
- 在
A2
声明一个足够的setter - 使用
abstract class
而不是接口