trait のミックスインはwithだけのがきれいだと思うのですが


トレイトのミックスインには extends か with を使いますが、何が違うのでしょうか。以下のトレイトがあった場合、

trait traitA
trait traitB

Foo クラスに traitA をミックインするには以下のようにします。

class Foo extends traitA

traitB のミックインも追加すると、

class Foo extends traitA with traitB

これは、traitA のスーパークラスである AnyRef を継承した以下のコードと同じ意味になります。

class Foo extends AnyRef with traitA with traitB

そして、以下のように書くことはできません。

class Foo with traitA with traitB  // エラー

extends はスーパークラスを指定するために使い、with はトレイトをミックスインするために使います。extends の後に1つ目のトレイト、その後はトレイトを with でつなぎます。

トレイト動的なミックスイン

トレイトは動的にミックスインすることもでき、その場合は extends は使わず、with を使います。

class Hoge
val g1:Hoge = new Hoge with traitA with traitB

クラス定義も extends ではなく with で指定した方がきれいな気がしますが・

Javaファイルへデコンパイルすると

traitA と traitB は以下の Java インターフェースとなります。

public abstract interface traitA{ }
public abstract interface traitB{ }

Foo クラス

class Foo extends traitA with traitB

は以下のようなJavaファイルとなります。

public class Foo implements traitA, traitB, ScalaObject {
  ・・・
}

動的にミックスインした

val g1:Hoge = new Hoge with traitA with traitB

は以下のようなJavaクラスとなります。

public final class Sample006$$anon$1 extends Hoge implements traitA, traitB{}