接口中的属性不能有支持字段
Posted
技术标签:
【中文标题】接口中的属性不能有支持字段【英文标题】: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 接口可以提供实现,并且可以具有带有访问器的属性。为什么编译失败?
我无法理解错误。它说什么?谁能简单的解释一下?
【问题讨论】:
【参考方案1】:这是一个意想不到的角落案例,感谢您找到它。
让我简要解释一下发生了什么。为了简单起见,我将使用剥离接口A
和类B
:
interface A
var notifier: Int
通常,类中的 var
属性包括 3 个组件:用于存储其值的私有 backing field
、用于写入它的 setter
方法和用于读取它的 getter
方法。但是一个接口不能有一个字段(因为 live 很痛苦,如果有的话,一些数学不会加起来),所以接口中的 var
属性只包含两个组件: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
可能的解决方法:
在A2
中声明一个适当的setter
使用abstract class
而不是接口
【讨论】:
我最终使用了抽象类。但令人沮丧的是,我在任何地方都找不到任何文档。谢谢你的回答。 如果您在 JetBrains 问题跟踪器上报告,请不要忘记在此处给我发送链接。谢谢! 太棒了!非常感谢。 您可以使用 val 代替 var (如果它适合您的目的),只需定义 get() 而不使用 set()(案例 A3) 对该问题进行了投票。两年多过去了,它仍然困扰着 Kotlin。以上是关于接口中的属性不能有支持字段的主要内容,如果未能解决你的问题,请参考以下文章