[Scala]入門 trait
以下の連載の7回目読んだ。
http://www.atmarkit.co.jp/ait/kw/scala.html
インターフェース的な存在がトレイト(trait)。ただし実装も書ける。コンストラクタも書けるが引数は渡せない。
複数のトレイトを継承することをミックスインという。コンストラクタはミックスインした左側から順に呼ばれる。
一つめのトレイトはextendsで、二つ目以降はwithを使う。なぜwithだけでないのか謎。
trait Base{ def print() = println("base") def write() } trait Piyo { def piyo() = println("Piyo") } class Hoge extends Base with Piyo{ def write = println("hoge") }
インスタンス化する時にもミックスインできる
val fuga = new Fuga with Piyo fuga.piyo
指定したトレイトのメソッドを呼ぶ
trait Base{ def print() = println("base") } trait Piyo { def piyo() = println("Piyo") def print() = piyo() } class Hoge extends Base with Piyo{ override def print() = super[Piyo].print }
複数のトレイトを実装した無名クラスも作れる
val foo = new Base with Piyo{ def write = println }
abstract override★
テンプレートメソッドパターン的なことができる。
trait Base{ def work(time : Int) } trait Half extends Base{ abstract override def work(time:Int) = super.work(time/2) } trait Sub extends Base{ abstract override def work(time:Int) = super.work(time-10) } class Worker extends Base{ def work(time:Int) = println(time) } -- val worker = new Worker() with Half worker.work(100) //Half.work→Worker.workが呼ばれる。出力値は50 val worker2 = new Worker() with Half with Sub worker.work(100) //Sub.work→Half.work→Worker.workが呼ばれる。出力値は(100-10)/2で45
メソッド呼び出しは基本的にはwithの右側から解決。基本でない場合はトレイトの線形化でぐぐる。