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 件のコメント:
コメントを投稿