- 実装を持つことができる。
- クラスは(Java の Interface と同様に) 複数の trait を実装することができる。
(ちなみに、trait を実装することを Scala では ミックスイン というらしい。)
Scala は Java の上で動くわけなので Java でできないことはできないわけなのだが、どのように実現されているのだろうか?
例外を発生させてスタックトレースを見てみることにする。
まずは、普通にクラスを extends した場合。
object TraitSample { def main(args : Array[String]) { new English().hello(); } } class Greetable { def hello() : String = { throw new IllegalArgumentException("in Greetable"); } } class English() extends Greetable { }
Exception in thread "main" java.lang.IllegalArgumentException: in Greetable at Greetable.hello(TraitSample.scala:9) at TraitSample$.main(TraitSample.scala:3) at TraitSample.main(TraitSample.scala)
普通に見慣れた感じのスタックトレース。スタック中に English.hello()は出現していない。
次に、trait を使ってみる。
object TraitSample { def main(args : Array[String]) { new English().hello(); } } trait Greetable { def hello() : String = { throw new IllegalArgumentException("in Greetable"); } } class English() extends AnyRef with Greetable { }
Exception in thread "main" java.lang.IllegalArgumentException: in Greetable at Greetable$class.hello(TraitSample.scala:9) at English.hello(TraitSample.scala:13) at TraitSample$.main(TraitSample.scala:3) at TraitSample.main(TraitSample.scala)
ふむ。
このスタックトレースを見ると、まず実装クラスの English.hello() が実行されて、そこから、Greetable$class.helloというクラスが呼び出されていることがわかる。
つまり、実装クラスにメソッドが生成されるとともに 実装 trait のオブジェクトも生成されていて、 実装クラスのメソッドから実装 trait オブジェクトのメソッドが実行される、という構造になっているようだ。
0 件のコメント:
コメントを投稿