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

时间:2016-06-08 11:08:59

标签: 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

Foo是一个类的情况下的行为相同。

2 个答案:

答案 0 :(得分:16)

  

这是正常还是预期?

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

  1. 仅在超类型中声明。
  2. 仅在子类型中声明。
  3. 在两者中声明,但不允许子类型更改默认值。
  4. 在两者中声明,允许子类型覆盖超类型中的默认值。
  5. Kotlin设计师选择了#1选项。这是有道理的,因为:

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

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

    这使得选项#1成为唯一合理的选择。

答案 1 :(得分: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
    }
}

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