traitの宣言と利用
trait は、Javaで言うインターフェースのようなものですが、メソッドのボディを持つことができる点が大きな違いとなります。
trait は以下のように定義します。
trait Friendly { def greet() = "Hi" }
この例では、greet メソッドは"Hi"というString型の文字列を返却します。最後に評価された式の"Hi"が返却されるためです。
traitのミックスインにはextendsキーワードかwithキーワード(1つ目にはextends、それ以降はwith)を使います。Scalaではimplements はキーワードではありません。
そして、クラスはtraitをいくつでも実装できます。
class Dog extends Friendly { override def greet() = "Woof" }
この例では、DogはtraitであるFriendlyを拡張しています。この継承関係は、Javaでのインターフェースの実装と同じことになります。このときoverrideキーワードを書かないとコンパイルできません。
Dogクラスを使うには、以下のようにします。
var pet: Friendly = new Dog println(pet.greet())
Dogのインスタンスは、Friendly型として扱うことができるようになります。
ミックスイン
traitはインスタンス化時にミックスインできます。
以下の例では、Dogのインスタンス化時にExclamatoryGreeterの実装を追加しています。
trait Friendly { def greet() = "Hi" } class Dog extends Friendly { override def greet() = "Woof" } trait ExclamatoryGreeter extends Friendly { override def greet() = super.greet() + "!!!" } object Example015 extends Application { val pup: Friendly = new Dog with ExclamatoryGreeter println(pup.greet()) //Woof!!! }
上記例ではDogとExclamatoryGreeterの合成型が作られ、"Woof!!!" と表示されます!!