假设以下示例 - 执行时返回 - " fatherfather"
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()
}
}
查看编译器的作用 - 更好地解释正在发生的事情
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>();
()
}
}
}
请详细说明为什么这是预期的行为?
答案 0 :(得分:5)
因为Scala规范说它应该如何工作。 Section 5.1.4 (Overriding):
重写方法从中继承所有默认参数 超类中的定义。通过在。中指定默认参数 覆盖方法可以添加新的默认值(如果是 超类中的相应参数没有默认值)或 覆盖超类的默认值(否则)。
在内部,指向JVM的Scala实现必须将默认参数存储为声明类的成员,因为JVM doesn't directly support default arguments on methods。
答案 1 :(得分:0)
在 Scala 中,默认参数将创建一个默认字段来保存此值,当您调用不带参数的方法时,编译器将自动设置默认参数作为此方法的参数。像:
revokeAction.doSomething(revokeAction.doSomething$default$1());
作为反编译代码,默认参数由类Action
中设置:
<synthetic> def doSomething$default$1(): String = "father";
当您在没有doSomething
的情况下调用parameter s
方法时,它正在调用:
revokeAction.doSomething(revokeAction.doSomething$default$1());
使用默认参数:revokeAction.doSomething$default$1()
,因为RevokeAction
不是override
def doSomething$default$1()
,所以默认参数仍为father
:
<synthetic> def doSomething$default$1(): String = RevokeAction.super.doSomething$default$1();