属性 界面中不能有支持字段
Property in interface cannot have a backing field
我正在学习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
编译时出现错误:属性 in interface cannot have a backing field。
根据文档 here,kotlin 接口可以提供实现并且可以具有访问器的属性。为什么编译失败?
我无法理解这个错误。它说什么?谁能简单解释一下?
这是一个出乎意料的极端案例,感谢您的发现。
让我简单解释一下这是怎么回事。为了简单起见,我将使用剥离的接口 A
和 class B
:
interface A {
var notifier: Int
}
通常 class 中的 var
属性 包含 3 个组件:一个用于存储其值的私有 backing field
,一个用于写入的 setter
方法它和一个 getter
方法来读取它。但是一个接口不能有一个字段(因为生活是痛苦的,如果有的话,一些数学不会加起来),所以接口中的 var
属性 只包含 2 个组件: setter
和 getter
.
正如我在上面概述的那样,我们的接口 A
声明了 2 个方法:一个 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
可能的解决方法:
- 声明足够的 setter 如
A2
- 使用
abstract class
而不是接口
我正在学习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
编译时出现错误:属性 in interface cannot have a backing field。
根据文档 here,kotlin 接口可以提供实现并且可以具有访问器的属性。为什么编译失败?
我无法理解这个错误。它说什么?谁能简单解释一下?
这是一个出乎意料的极端案例,感谢您的发现。
让我简单解释一下这是怎么回事。为了简单起见,我将使用剥离的接口 A
和 class B
:
interface A {
var notifier: Int
}
通常 class 中的 var
属性 包含 3 个组件:一个用于存储其值的私有 backing field
,一个用于写入的 setter
方法它和一个 getter
方法来读取它。但是一个接口不能有一个字段(因为生活是痛苦的,如果有的话,一些数学不会加起来),所以接口中的 var
属性 只包含 2 个组件: setter
和 getter
.
正如我在上面概述的那样,我们的接口 A
声明了 2 个方法:一个 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
可能的解决方法:
- 声明足够的 setter 如
A2
- 使用
abstract class
而不是接口