在接口中从 class 覆盖并实现 fn

override and implement fn from class in interface

我想重写接口中的 toString() 并让实现该接口的对象默认使用该方法(例如:未隐藏)

interface SingletonObjectTrait {
  fun toString(): String = this.javaClass.simpleName
}

有没有直接的方法来定义这样的接口,最好在实现时使用最少的配置

object MyEvent: SomeEventLogic(), SomeEventType, SingletonObjectTrait
class SomeEventLogic {}
interface SomeEventType {}

恐怕这不可能。

接口中的方法实现与 Java 中的默认方法非常相似:仅当实现 class 还没有实现时才使用它们。但是 every class 已经从 Any 继承了 toString(),因此永远不会使用默认值。

事实上,编译器对此有一个特定的错误——如果你试图在一个接口中实现 toString(),它会说:

An interface may not implement a method of 'Any'

我看不出解决这个问题的好方法。

正如 Erik 所说,一种选择是将接口更改为抽象接口 class;但是如果任何实现已经扩展了另一个 class.

当然那是不可行的

另一种选择可能是在接口中实现 different 方法,并在注释中指示实现 classes 以覆盖 toString() 并调用它方法。不是自动的,但实施者的工作更少,重复更少。

除了使用注解处理器在编译时添加缺失的覆盖之外,没有其他好的方法(通过向检测到的接口添加注解并生成在实现中覆盖 class)。 这可行,但可能比你想要的要多,并且可能超出了 Stack Overflow 上的答案范围(寻找“如何编写一个Java 或 Kotlin 的注释处理器”和“KAPT”(对于支持 Kotlin 处理器的一个引擎)。

回到你的代码,为什么它不能按原样工作:

接口中的方法不能具有与 Any class 中的任何方法相匹配的签名。如果你试图覆盖其中之一,你会得到一个编译错误。

An interface may not implement a method of 'Any'

做你想做的事情的最少代码是:

interface SingletonObjectTrait {
    fun asString(): String = this.javaClass.simpleName
}

open class SomeEventLogic {}
interface SomeEventType {}

object MyEvent: SomeEventLogic(), SomeEventType, SingletonObjectTrait {
    override fun toString(): String = asString() // hope they don't forget to call this!
}

无法保证实施者会调用特征 asString() 函数,但至少您可以在实施 class.

中与一行代码共享该功能