我有以下基类和接口

open class Base {
    open fun foo() { println("Base.foo") }
}

fun interface Delegate {
    fun foo(): Unit
}

现在,我想使用委托重写Base子类Composedfoo方法,如下所示:

class Composed(delegate: Delegate) : Base(), Delegate by delegate

这是我想要的.Composed的实例使用delegatefoo方法,而不是Base的方法.But,我收到IntelliJ的警告:

委托成员"fun foo():Unit"隐藏超类型重写:public open fun foo():在基中定义的单元.请明确指定正确的覆盖.

为什么会出现此错误?隐式重写foo方法的"坏处"是什么?有什么缺点我看不出来吗?显式指定重写似乎有很多不必要的代码,特别是如果我对多个方法和多个子类这样做的话.

推荐答案

我认为有一个警告至少有两个原因:

  1. 对于使用哪个foo()实现,行为是不明确的.由于超类和代理被声明在同一行上,所以对于哪一个foo()应该获胜没有直观的预期.我已经使用Kotlin几年了,如果不测试它,我就无法告诉您期望的行为,因为这是一种不寻常的设置.

  2. 如果基超类中的任何函数调用foo(),则可能会出现意外行为,因为它们将调用委托的foo()而不是自己的foo().在这种情况下可能没问题,但在大多数情况下,当您重写函数时,您希望调用super以防出现必要的副作用.对于代表来说,这是不可能的.

Kotlin相关问答推荐

如何在 Big Data 中使用Inc过滤器?

如何在操作系统版本上正确获取Room数据库的路径>;=26 sdk?

判断 Kotlin 变量是否为函数

如果不为空,则为 builder 设置一个值 - Kotlin

这是什么 Kotlin 类型:(String..String?)

TestContainers PostgreSQLContainer 与 Kotlin 单元测试:Not enough information to infer type variable SELF

从 Java 调用 Kotlin 高阶函数

kotlin,如何从函数返回类类型

如何从 Firestore 查询中排除元素?

使用kotlinx协同程序测试中的类时出错

Kapt不适用于Android Studio 3.0中的AutoValue

无法在Kotlin中使用argb color int值?

API 26 上未显示 Android 通知

从命令行运行Java到Kotlin转换器?

如何为 Java 调用者声明返回类型为void的 Kotlin Lambda?

如果作为 RxJava Observable 提供,Kotlin 密封类子类需要强制转换为基类

android Room 将 Null 作为非 Null 类型返回

如何根据ArrayList的对象属性值从中获取最小/最大值?

Kotlin 中内部可见性修饰符的范围

用 kotlin 学习 Android MVVM 架构组件