【发布时间】:2016-07-15 11:34:25
【问题描述】:
接口的函数名故意与属性的getter名冲突,但由于意外覆盖问题被编译器禁止。是否可以指示编译器这是故意的?
interface A {
fun getFoo()
}
class B: A {
val foo
}
【问题讨论】:
标签: kotlin
接口的函数名故意与属性的getter名冲突,但由于意外覆盖问题被编译器禁止。是否可以指示编译器这是故意的?
interface A {
fun getFoo()
}
class B: A {
val foo
}
【问题讨论】:
标签: kotlin
此功能似乎没有以任何方式实现。
@AndreyBreslav 对similar question 的评论:
目前您不能使用 Kotlin 属性覆盖 Java 方法。如果我们可以支持它会很好,但我们不知道如何为混合层次结构始终如一地做到这一点
这并不能解决您的问题,但至少可以编译代码:您可以使用 @JvmName annotation 更改 getter 的 JVM 名称:
interface A {
fun getFoo(): SomeType
}
class B: A {
override fun getFoo() = foo
val foo: SomeType = someValue()
@JvmName("getFoo_") get() = field
}
另外,考虑更改为更惯用的方法:在您的界面中定义 val-property,以便您可以在实现中覆盖它:
interface A {
val foo: SomeType
}
class B : A {
override val foo: SomeType = someValue()
}
class C : A {
override val foo: SomeType
get() = someCustomGetter()
}
【讨论】:
在我们坚持使用 Kotlin 之前,上述答案中的 Kotlin 惯用方法是可以的,但如果这些接口是用 Java 定义的,则它不适用。 KT-6653 中报告了很多提议,但目前都没有实施。我目前正在编写一些部分使用 Java 部分使用 Kotlin 的应用程序,这个问题完全扼杀了“Kotlin-Java 互操作性”的概念。
我发现的唯一解决方法是:
public interface A {
String getFoo();
}
class B(private val _foo: String): A {
override fun getFoo(): String = _foo
}
也可以用 setter 扩展这个类:
class B(private var _foo: String): A {
override fun getFoo(): String = _foo
fun setFoo(foo: String) {
_foo = foo
}
}
【讨论】: