2009年12月11日金曜日

[Scala] Trait って何者 (1)

Java の interface のような abstract class のような、形容しがたい Trait.
javap で実体を少しだけのぞいてみました。

単純なサンプル
// animal.scala

// メンバーをもたないTrait
trait Animal

// 抽象メソッドだけをもつTrait
trait HasLegs extends Animal {
def legs: Int
}

// 具象メソッドをもつTrait
trait HasFourLegs extends HasLegs {
def legs: Int = 4
}

// Traitを継承するクラス
class Cat extends HasFourLegs

// Traitを継承&Mixinするクラス
class Dog extends Animal with HasFourLegs


コンパイルすると、こんな感じでクラスファイルができます。

- Animal.class
- HasLegs.class
- HasFourLegs.class
- HasFourLegs$class.class
- Cat.class
- Dog.class

見慣れないのは、HasFourLegs$class.class というクラスファイル。

それぞれ javap にかけてみます。


$ javap Animal
Compiled from "animal.scala"
public interface Animal{
}


Animal は、空のインタフェース。


$ javap HasLegs
Compiled from "animal.scala"
public interface HasLegs extends Animal{
public abstract int legs();
}


HasLegs は、Animal を継承して、メソッドをひとつだけ持つインタフェース。


$ javap HasFourLegs
Compiled from "animal.scala"
public interface HasFourLegs extends HasLegs,scala.ScalaObject{
public abstract int legs();
}


HasFourLegs は、HasLegs と ScalaObject を継承して、legs() メソッドをもつインタフェース。


$ javap HasFourLegs\$class
Compiled from "animal.scala"
public abstract class HasFourLegs$class extends java.lang.Object{
public static void $init$(HasFourLegs);
public static int legs(HasFourLegs);
}


HasFourLegs$class は、具象メソッド legs() をもつアブストラクトクラス。

推測するに、具象メソッドをもつ HasFourLegs Trait は、Java のインタフェースとアブストラクトクラスを駆使(?)して実現されているようです。

では、Traitを継承、Mixinするクラスのほうは。


$ javap Cat
Compiled from "animal.scala"
public class Cat extends java.lang.Object implements HasFourLegs,scala.ScalaObject{
public Cat();
public int $tag() throws java.rmi.RemoteException;
public int legs();
}


Cat は、HasFourLegs を implement しています。HasFourLegs$class を継承するわけではないらしい。


$ javap Dog
Compiled from "animal.scala"
public class Dog extends java.lang.Object implements Animal,HasFourLegs,scala.ScalaObject{
public Dog();
public int $tag() throws java.rmi.RemoteException;
public int legs();
}


Dog は、Animal と HasFourLegs を implement しています。
Trait を extends するにせよ with で Mixin するにせよ、コンパイル後は同じなのか。

0 件のコメント:

コメントを投稿