Вот оно:
Короче говоря, 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!
Google больше за «шаблон стека», это отличная вещь!:)
Ооо ... Я забыл про Java:)
Для данного примера у нас будет Shouter.class - интерфейс 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
.Он реализует интерфейс 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.
Вот оно.