具有默认参数的覆盖特征方法

Ami*_*Paz 3 scala

假设以下示例-执行后返回-“父亲”

trait Action {
    def doSomething(s:String = "father") = s
}

class RevokeAction extends Action{
    override def doSomething(s:String) = {
        s + s
    }
}

object HelloWorld {
  def main(args: Array[String]): Unit = {
    val revokeAction = new RevokeAction()
    revokeAction.doSomething()
  }
}
Run Code Online (Sandbox Code Playgroud)

查看编译器的功能-更好地说明正在发生的事情

package <empty> {
  abstract trait Action extends Object {
    def doSomething(s: String): String = s;
    <synthetic> def doSomething$default$1(): String = "father";
    def /*Action*/$init$(): Unit = {
      ()
    }
  };
  class RevokeAction extends Object with Action {
    <synthetic> def doSomething$default$1(): String = RevokeAction.super.doSomething$default$1();
    override def doSomething(s: String): String = s.+(s);
    def <init>(): RevokeAction = {
      RevokeAction.super.<init>();
      RevokeAction.super./*Action*/$init$();
      ()
    }
  };
  object HelloWorld extends Object {
    def main(args: Array[String]): Unit = {
      val revokeAction: RevokeAction = new RevokeAction();
      {
        revokeAction.doSomething(revokeAction.doSomething$default$1());
        ()
      }
    };
    def <init>(): HelloWorld.type = {
      HelloWorld.super.<init>();
      ()
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

请详细说明为什么这是预期的行为吗?

Yuv*_*kov 6

因为这就是Scala规范所说的应该起作用的方式。第5.1.4节(覆盖)

重写方法从超类的定义继承所有默认参数。通过在重写方法中指定默认参数,可以添加新的默认值(如果超类中的对应参数没有默认值)或覆盖超类的默认值(否则)。

在内部,指示JVM的Scala实现必须将默认参数存储为声明类的成员,因为JVM 不直接支持method的默认参数