Scala Trait(トレイト)

Scala の Trait(トレイト)は Java のインターフェースに相当しますが、実際にはインターフェースよりも強力です。

インターフェースと異なり、プロパティ(属性)やメソッドの実装も定義できます。

通常、Scala のクラスは単一のスーパークラスのみ継承できますが、Trait(トレイト)の場合には複数継承できます。結果として多重継承を実現しています。

Trait(トレイト)の定義方法はクラスと似ていますが、使用するキーワードはtrait、次に示すとおりです。

例

trait Equal {
  def isEqual(x: Any): Boolean
  def isNotEqual(x: Any): Boolean = !isEqual(x)
}

上記の Trait(トレイト)は2つのメソッドで構成されます:isEqualとisNotEqual。isEqual メソッドはメソッドの実装を定義しておらず、isNotEqual はメソッドの実装を定義しています。サブクラスはトレイトを継承して未実装のメソッドを実装できます。つまり、実際には Scala の Trait(トレイト)は Java の抽象クラスに似ています。

以下にトレイトの完全な例を示します:

例

/* ファイル名:Test.scala
* author:サンプル
 * url:www.example.com
 */

trait Equal {
  def isEqual(x: Any): Boolean
  def isNotEqual(x: Any): Boolean = !isEqual(x)
}

class Point(xc: Int, yc: Int) extends Equal {
  var x: Int = xc
  var y: Int = yc
  def isEqual(obj: Any) =
    obj.isInstanceOf[Point] &&
    obj.asInstanceOf[Point].x == x
}

object Test {
   def main(args: Array[String]) {
      val p1 = new Point(2, 3)
      val p2 = new Point(2, 4)
      val p3 = new Point(3, 3)

      println(p1.isNotEqual(p2))
      println(p1.isNotEqual(p3))
      println(p1.isNotEqual(2))
   }
}

上記のコードを実行すると、出力結果は次のとおりです:

$ scalac Test.scala 
$ scala Test
false
true
true

トレイトの構築順序

トレイトもコンストラクタを持つことができ、フィールドの初期化と他のトレイト本体の文で構成されます。これらの文は、そのトレイトをミックスインしたオブジェクトが構築される際に必ず実行されます。

コンストラクタの実行順序:

  • スーパークラスのコンストラクタを呼び出す;
  • トレイトのコンストラクタはスーパークラスのコンストラクタの後、クラスのコンストラクタの前に実行される;
  • トレイトは左から右へ構築される;
  • 各トレイトの中で、親トレイトが先に構築される;
  • 複数のトレイトが同じ親トレイトを持つ場合、親トレイトは繰り返し構築されない
  • すべてのトレイトが構築されると、サブクラスが構築される。

コンストラクタの順序はクラスの線形化の逆順です。線形化は、ある型のすべてのスーパータイプを記述する技術仕様です。

その他の拡張