gpt4 book ai didi

kotlin - 生成的 setter 与接口(interface)方法冲突

转载 作者:行者123 更新时间:2023-12-02 03:34:17 24 4
gpt4 key购买 nike

我正在编写一个类,该类实现一个公开 setSelected 方法的接口(interface)。这个类将有一个 selected 属性:

private class Foo : IFoo {
var selected = false

override fun setSelected(isActive: Boolean) {
selected = isActive
}

}

然而,编译器提示,因为 Kotlin 为 selected 生成了一个 setter,这两个方法发生冲突:

Error:(14, 9) Kotlin: [com.bar.jvmTest] Platform declaration clash: The following declarations have the same JVM signature (setSelected(Z)V):
fun <set-selected>(<set-?>: Boolean): Unit defined in foo.bar.baz.Foo
fun setSelected(isActive: Boolean): Unit defined in foo.bar.baz.Foo
Error:(24, 9) Kotlin: [com.bar.jvmTest] Platform declaration clash: The following declarations have the same JVM signature (setSelected(Z)V):
fun <set-selected>(<set-?>: Boolean): Unit defined in foo.bar.baz.Foo
fun setSelected(isActive: Boolean): Unit defined in foo.bar.baz.Foo
<小时/>

  • 我很想删除自定义方法来利用 setter,但它没有被标记为覆盖,因此我的类没有完全实现该接口(interface):

    Error:(11, 13) Kotlin: [com.bar.jvmTest] Class 'Foo' is not abstract and does not implement abstract member public abstract fun setSelected(isActive: Boolean): Unit defined in bar.baz

  • 我知道我可以将selected重命名为例如dataSelected 以便生成的 setter 不会与该方法发生冲突,但应该有一种方法来保持这个简单的属性名称​​并按预期实现接口(interface)。
  • 有没有办法要求 Kotlin 编译器不为该属性生成 setter,或者将其标记为覆盖

    最佳答案

    您可以创建一个没有支持字段的属性,然后重写您的抽象函数,如下所示:

    class Foo : IFoo {
    private var hiddenSelected = false

    val selected get() = hiddenSelected

    override fun setSelected(isActive: Boolean) {
    hiddenSelected = isActive
    }
    }

    更新:

    睡了一觉之后,我认为这个解决方案根本不是那么好,因为有两个原因:

    1. 它引入了一个不必要的新字段 (hiddenSelected)
    2. 您无法使用标准 Kotlin 方式(= 运算符)对该字段进行赋值

    我认为最好的解决方案是这样的:

    class Foo : IFoo {
    @set:JvmName("setSelected0")
    var selected: Boolean = false
    set(value) { setSelected(value) }

    override fun setSelected(isActive: Boolean) {
    // Possibly some other stuff
    println("Now i'm using my own setter!")
    selected = isActive
    }
    }

    使用注释@JvmName您可以告诉编译器如何命名该特定函数。 Kotlin 会自动为每个属性创建一个 getter 和 setter,因此您需要使用 set: 修饰符来注释该属性的 setter,而不是属性本身。

    此外,为该属性实现自定义 setter 也非常重要,这样您就可以安全编写以下内容:

    Foo().selected = true // This also prints "Now i'm using my own setter!"

    而不是这个:

    Foo().setSelected(true)

    您的 setter 可能会执行其他一些操作(例如打印日志),这可能会产生副作用,因此您需要确保调用正确的 setter。这有时可能有点棘手,因为 Kotlin 总是为每个可变变量 (var) 创建一个 setter。

    关于kotlin - 生成的 setter 与接口(interface)方法冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55148260/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com