为什么可以省略子类型的重写成员函数中的默认值?

EPa*_*onU 16 kotlin

正如标题中所述:为什么可以省略子类型的重写成员函数中的默认值?

这是正常的还是预期的?

interface Foo {
  fun bar(parameter: Int = 1)
}

class Baz : Foo {
  override fun bar(parameter: Int) { // OK
    println(parameter)
  }
}

val baz = Baz()

baz.bar() // OK
baz.bar(2) // OK
Run Code Online (Sandbox Code Playgroud)

Foo属于类的情况下的行为相同.

Ram*_*man 17

这是正常的还是预期的?

是.

我怀疑这主要是语言设计/可用性决策.从这个角度来看,有四种选择:

  1. 仅以超类型声明.
  2. 仅在子类型中声明.
  3. 在两者中声明,但不允许子类型更改默认值.
  4. 在两者中声明,允许子类型覆盖超类型中的默认值.

Kotlin设计师选择了#1选项.这是有道理的,因为:

选项#2和#4都意味着调用者不知道默认值是什么,除非他们知道他们正在使用哪种实现,这当然是非常不受欢迎的.调用者需要额外的逻辑来确定是否需要一个值来覆盖默认值,这意味着默认值是无用的.

选项#3违反了DRY原则.为什么要强制声明在两个地方?

这使选项#1成为唯一理智的选择.


vod*_*dan 7

是的,这是正常的,也是可以预期的.

更结束了,这是容许覆盖默认值.这不编译:

interface Foo {
    fun bar(parameter: Int = 1)
}

class Baz : Foo {
    override fun bar(parameter: Int = 1) { // ERROR: An overriding function is not allowed to specify default values for its parameters
    }
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,具有固定默认值的实现比任何其他实现简单得多.例如,Scala在很大程度上提供了这种功能,但生成的字节代码并不简单.