【问题标题】:Property in interface cannot have a backing field接口中的属性不能有支持字段
【发布时间】:2017-04-26 08:45:32
【问题描述】:

我正在学习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 

编译时出现错误提示:接口中的属性不能有支持字段

从文档here 来看,kotlin 接口可以提供实现,并且可以具有带有访问器的属性。为什么编译失败?

我无法理解错误。它说什么?谁能简单的解释一下?

【问题讨论】:

    标签: android properties kotlin kotlin-android-extensions


    【解决方案1】:

    这是一个意想不到的角落案例,感谢您找到它。

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

    interface A {
        var notifier: Int
    }
    

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

    如上所述,我们的接口 A 声明了 2 个方法:settergetter,两者都没有实现。让我们为其添加一些实现:

    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。换句话说,A3A4 相似:

    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 而不是接口

    【讨论】:

    • 我最终使用了抽象类。但令人沮丧的是,我在任何地方都找不到任何文档。谢谢你的回答。
    • 如果您在 JetBrains 问题跟踪器上报告,请不要忘记在此处给我发送链接。谢谢!
    • 太棒了!非常感谢。
    • 您可以使用 val 代替 var (如果它适合您的目的),只需定义 get() 而不使用 set()(案例 A3)
    • 对该问题进行了投票。两年多过去了,它仍然困扰着 Kotlin。
    猜你喜欢
    • 2013-05-06
    • 1970-01-01
    • 2011-10-05
    • 2021-12-13
    • 2021-12-02
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多