接口中的属性不能有后备字段

Kru*_*hah 7 android properties kotlin kotlin-android-extensions

我正在学习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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,当我更改它并尝试为以下属性提供访问器时:

var notifier: A?
    get() = notifier 
Run Code Online (Sandbox Code Playgroud)

它没有编译错误说:接口中的属性不能有支持字段.

从这里的doc ,kotlin接口可以提供实现,并且可以具有访问器的属性.为什么编译失败?

我无法理解错误.它说什么?任何人都可以简单地解释一下吗

vod*_*dan 11

这是一个意想不到的角落案例,对你的发现感到荣幸.

让我简要解释一下发生了什么.为简单起见,我将使用剥离的接口A和类B:

interface A {
    var notifier: Int
}
Run Code Online (Sandbox Code Playgroud)

通常var,类中的属性包括3个组件:backing field用于存储其值的private ,setter用于写入它的getter方法以及用于读取它的方法.但是一个接口不能有一个字段(因为实时是痛苦的,如果有的话,一些数学不会加起来),所以var接口中的属性只包含2个组件:a setter和a getter.

如上所述,我们的接口A声明了两种方法:a setter和a getter,两者都没有实现.让我们为它添加一些实现:

interface A2 {
    var notifier: Int
        get() {return 1}
        set(v) {}
}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.两种open实现方法,不使用任何字段.但是,如果只宣布其中一个实现呢?

interface A3 {
    var notifier: Int    //ERROR: Property in an interface cannot have a backing field
        get() {return 1}
        //set(v) {}
}
Run Code Online (Sandbox Code Playgroud)

事实证明,如果你只指定一个getter,Kotlin也会setter为该属性生成一个(默认).换句话说,A3类似于A4这里:

interface A4 {
    var notifier: Int
        get() {return 1}
        set(v) {field = v}  //Obviously an error
}
Run Code Online (Sandbox Code Playgroud)

这可能是一个错误或预期的行为.这是发行票:https://youtrack.jetbrains.com/issue/KT-15193

可能的解决方法:

  • 宣布一个适当的制定者,如 A2
  • 使用abstract class而不是接口