かとじゅんの技術日誌

技術の話をするところ

Re: Scala の Trait

trait 便利ですね!

メソッド名が衝突する。 override を指定してやると動く。
scala> (new M with N { override def m = super[N].m }).m()
hi
@rosylilly Scala の Trait

trait Mとtrait Nは継承関係もないので別の型として識別されているから仕方ないんだろうなと推測。まぁ静的型付強い言語でこのような解決手段を提供しているのは、単純にすごいなと思う。とはいえ、もうちょい楽できないかという話はある。というとで、やはり型を意識した方が楽になるね!!! ってことで考えてみた。

次の例では、自分型アノテーションを使って、trait Nはtrait Mにしかミックスインできないようにしてみた。trait Nを定義する時点でメソッドmにoverrideを付与する。 つまりwithで結合した順番で実装が上書きされることになる。

scala> class M { def m = println("hello") }
defined class M

scala> trait N { this: M => override def m = println("hi") }
defined trait N
scala> (new M with N).m
hi

次は、trait Lという型を定義し、それを継承したtrait M, Nを用意する。この例では、結合する trait とその順番を変えれば振る舞いを変更することができるようになる。1

scala> trait L { def m: Unit }
defined trait L

scala> trait M extends L { override def m = println("hello") }
defined trait M

scala> trait N extends L { override def m = println("hi") }
defined trait N

scala> (new N with M).m
hello

scala> (new M with N).m
hi

Rubyのmix-inとはだいぶ違う気がするねー。