Interface的功能与Property的getter冲突

Eug*_*ene 23 kotlin

接口的函数名称故意与属性的getter名称冲突,但由于意外覆盖问题,编译器禁止它.有可能指示编译器这是故意的吗?

interface A {
  fun getFoo()
}

class B: A {
  val foo
}
Run Code Online (Sandbox Code Playgroud)

hot*_*key 21

此功能似乎无法以任何方式实现.

@ AndreyBreslav对类似问题的评论:

您目前无法使用Kotlin属性覆盖Java方法.如果我们能够支持它会很好,但我们不知道如何为混合层次结构一致地做到这一点


这不能解决您的问题,但至少会使代码编译:您可以使用@JvmName注释更改getter的JVM名称:

interface A {
    fun getFoo(): SomeType
}

class B: A {
    override fun getFoo() = foo

    val foo: SomeType = someValue()
        @JvmName("getFoo_") get() = field
}
Run Code Online (Sandbox Code Playgroud)

另外,请考虑更改为更惯用的方法:val在您的界面中定义-property,以便您可以在实现中覆盖它:

interface A {
    val foo: SomeType
}

class B : A {
    override val foo: SomeType = someValue()
}

class C : A {
    override val foo: SomeType
        get() = someCustomGetter()
} 
Run Code Online (Sandbox Code Playgroud)

  • UPD:添加了更多Kotlin惯用的方法。 (2认同)

Luk*_*ski 5

在我们坚持使用 Kotlin 之前,上面答案中的 Kotlin 惯用方法是可以的,但如果这些接口是在 Java 中定义的,则它不适用。KT-6653中报告了很多提议,但目前没有一个得到实施。我目前正在编写一些应用程序,部分使用 Java,部分使用 Kotlin,这个问题完全扼杀了“Kotlin-Java 互操作性”概念。

我发现解决这个问题的唯一解决方案是以下一个:

public interface A {
  String getFoo();
}
Run Code Online (Sandbox Code Playgroud)
class B(private val _foo: String): A {

  override fun getFoo(): String = _foo

}
Run Code Online (Sandbox Code Playgroud)

也可以使用 setter 扩展此类:

class B(private var _foo: String): A {

  override fun getFoo(): String = _foo

  fun setFoo(foo: String) {
    _foo = foo
  }

}
Run Code Online (Sandbox Code Playgroud)