我找到a great explanation of how trait is compiled to Java code,但我认为它缺少“抽象覆盖”功能。为此功能生成了什么Java代码?
答案 0 :(得分:6)
来了:
简而言之,abstract override def m()
允许从方法中调用super.m()
,当一个特征在之后混合时,这个超级调用动态地取代了类型创建其他类型,例如
trait Printer {
def print(msg: String)
}
trait Shouter extends Printer {
abstract override def print(msg: String) { super.print(msg + "!") }
}
class ConsolePrinter extends Printer {
def print(msg: String) { println(msg) }
}
val loudPrinter = new ConsolePrinter with Shouter
loudPrinter.print("Scala is great")
这里我们混合了Shouter之后,在类型线性化之后变成'Shouter extends ConsolePrinter',并且对super.print()
的调用变为ConsolePrinter.print()
并且它给了我们:
Scala is great!
谷歌更多的是“可堆叠的特质模式”,这是一件好事! :)
Agh ......我忘记了Java :)。
对于给定的示例,我们将使用Shouter.class - 接口Shouter和方法:
[0] Shouter$$super$print
[1] print
接下来,Shouter $ class.class - 具有静态方法print(LShouter;Ljava/lang/String;)V
的名为“Shouter $ class”的具体类和正文:
0 aload_0
1 new #8 <scala/collection/mutable/StringBuilder>
4 dup
5 invokespecial #12 <scala/collection/mutable/StringBuilder.<init>>
8 aload_1
9 invokevirtual #16 <scala/collection/mutable/StringBuilder.append>
12 ldc #18 <!>
14 invokevirtual #16 <scala/collection/mutable/StringBuilder.append>
17 invokevirtual #22 <scala/collection/mutable/StringBuilder.toString>
20 invokeinterface #28 <Shouter.Shouter$$super$print> count 2
25 return
即,在传递的实例上调用方法Shouter$$super$print(String)
。
接下来,$$anon$1.class
- 名为“$ anon $ 1”的具体类 - 这是我们的new ConsolePrinter with Shouter
。它实现了接口Shouter,即实现了它的方法。在这里:
print(Ljava/lang/String;)V
0 aload_0
1 aload_1
2 invokestatic #21 <Shouter$class.print>
5 return
Shouter$$super$print(Ljava/lang/String;)V
:
0 aload_0
1 aload_1
2 invokespecial #11 <ConsolePrinter.print>
5 return
也就是说,在被叫print()
中,我们正在调用static Shouter$class.print()
,这是来自Shouter特征的实现。该打印添加!
并在我们的对象上调用Shouter $$ super $ print()并将调用转发给ConsolePrinter。
就是这样。