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

最佳答案

它来了:

  • Traits and abstract methods override in Scala
  • Scala's Stackable Trait Pattern

  • 简而言之,abstract override def m() 允许从方法调用 super.m() 并且这个 super 调用动态地限制在类型创建的位置,例如,当一个特征在所有其他类型之后混合时
    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!
    

    谷歌更多的“可堆叠特征模式”,这是一件很棒的事情! :)

    啊...我忘记了 Java :)

    对于给定的示例,我们将拥有 Shouter.class - 带有方法的接口(interface) Shouter:
      [0] Shouter$$super$print
      [1] print
    

    接下来,Shouter$class.class - 名为“Shouter$class”的具体类,带有静态方法 print(LShouter;Ljava/lang/String;)V 和主体:
     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 。它实现了接口(interface)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(),它是 Souter trait 的一个实现。该打印添加 ! 并在我们的对象上调用 Shouter$$super$print() ,然后我们将调用转发到 ConsolePrinter。

    就这个。

    关于scala - Java 代码中的抽象覆盖如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9476126/

    10-09 15:49