抽象覆盖如何在Java代码方面起作用?

时间:2012-02-28 03:52:20

标签: scala traits

我找到a great explanation of how trait is compiled to Java code,但我认为它缺少“抽象覆盖”功能。为此功能生成了什么Java代码?

1 个答案:

答案 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。

就是这样。