从接口中的类覆盖和实现 fn

xst*_*xst 3 overriding traits kotlin

我想在一个接口中覆盖 toString() 并让实现该接口的对象默认使用该方法(例如:不隐藏)

interface SingletonObjectTrait {
  fun toString(): String = this.javaClass.simpleName
}
Run Code Online (Sandbox Code Playgroud)

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

object MyEvent: SomeEventLogic(), SomeEventType, SingletonObjectTrait
class SomeEventLogic {}
interface SomeEventType {}
Run Code Online (Sandbox Code Playgroud)

gid*_*dds 5

恐怕这是不可能的。

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

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

接口不能实现“Any”的方法

我找不到解决这个问题的好方法。

正如 Erik 所说,一种选择是将接口更改为抽象类;但是如果任何实现已经扩展了另一个类,那当然是不可行的。

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


Jay*_*ard 4

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

回到您的代码以及为什么它不能按原样工作:

接口的方法不能具有与类中任何方法相匹配的签名Any。如果您尝试覆盖其中之一,您将收到编译错误。

接口不能实现“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!
}
Run Code Online (Sandbox Code Playgroud)

不能保证实现者会调用特征asString()函数,但至少您可以与实现类中的单行代码共享功能。