= 自分型アノテーション = 自分型アノテーションの用途は二つある。 * thisの別名を定義する。 * クラスの機能を分割する。 == thisの別名を定義する == {{{ object SelfTypeAnnotationSample1 { self => // 自分型アノテーション。=>の右側には何もない。「class Internal」を指しているわけでもない。 class Internal { def procedure = { SelfTypeAnnotationSample1.this.procedure self.procedure } } def procedure = { println("hello world") } def main(args: Array[String]) { new Internal().procedure } } }}} この結果は {{{ hello world hello world }}} == クラスの機能を分割する == 一つのクラスの機能を複数のクラスに分割する場合、Javaでは一般に集約を行うが(継承はだめ)、Scalaではtraitによるミックスインという方法がある。 しかし、ミックスインでは機能を集約できるものの、その機能が外側から見えてしまう。 他のtraitの機能をターゲットのクラスにミックスインしつつ、そのtraitの存在を外部に教えないようにするために、自分型アノテーションを使うことができる(こういう説明でよいかわからない)。 以下では、SampleはSomeOtherを自分型として指定するが、これは抽象traitである。 Sampleのオブジェクト生成時に実装traitを指定する。 Sampleを使う側は、このオブジェクトがSomeOtherを利用していることは知らないし、そのメソッドにもアクセスすることはできない。 {{{ trait SomeOther { def something } trait SomeOtherImpl extends SomeOther { def something = { println("something") } } class Sample { self: SomeOther => def test = { something } } object SelfTypeAnnotationSample2 { def main(args: Array[String]) { object SampleImpl extends Sample with SomeOtherImpl; SampleImpl.test } } }}} この手法は「Cakeパターン」と呼ばれるDI手法と言われることがあるのだが、新たなパターンというよりも、「手によるコンストラクタ注入」の代用と言った方がよい。