Scala トレイトのサンプルコード
[履歴] (2015/04/26 07:36:14)
最近の投稿
注目の記事

概要

Scala のトレイトは実装のある Java インターフェースのようなものです。トレイトはクラスにミックスインして使用します。ミックスインは継承のようなものです。コード上ではクラス定義時に extends や with でトレイトを指定します。Scala は Java と同様に親クラスは一つまでしか指定できません。一方でトレイトは Java インターフェースのようにいくつでもミックスインできます。これによって多重継承のような需要は満たせます。継承ではなくミックスインですので、ダイヤモンド継承のように異なるミックスイン経路が二重三重に存在していても問題になりません。

サンプルコード

クラスからトレイトを extends で指定してミックスイン

trait.scala

object Main {
  def main(args: Array[String]) {
    val obj = new MyClass
    obj.myMethod
  }
}

trait MyTrait {
  def myMethod() {
    println("MyTrait::myMethod()")
  }
}

class MyClass extends MyTrait {
}

実行例

$ scalac trait.scala && scala Main
MyTrait::myMethod()

クラスにトレイトを with でミックスイン

一つのトレイトを指定

trait.scala

object Main {
  def main(args: Array[String]) {
    val obj = new MySubClass
    obj.myMethod
  }
}

trait MyTrait {
  def myMethod() {
    println("MyTrait::myMethod()")
  }
}

class MyClass {
}

class MySubClass extends MyClass with MyTrait {
}

実行例

$ scalac trait.scala && scala Main
MyTrait::myMethod()

複数のトレイトを指定

trait.scala

object Main {
  def main(args: Array[String]) {
    val obj = new MySubClass
    obj.myMethod
    obj.myMethod2
  }
}

trait MyTrait {
  def myMethod() {
    println("MyTrait::myMethod()")
  }
}

trait MyTrait2 {
  def myMethod2() {
    println("MyTrait2::myMethod()")
  }
}

class MyClass {
}

class MySubClass extends MyClass with MyTrait with MyTrait2 {
}

実行例

$ scalac trait.scala && scala Main
MyTrait::myMethod()
MyTrait2::myMethod()

オーバーライド

C++ オーバーライド (仮想関数とアップキャスト) で紹介したようなことが Scala でも実装できます。

trait.scala

object Main {
  def main(args: Array[String]) {
    val objA: MyTrait = myFunc('A')
    val objB: MyTrait = myFunc('B')
    val obj: MyTrait = myFunc('-')
    objA.myMethod //=> MyClassA::myMethod()
    objB.myMethod //=> MyClassB::myMethod()
    obj.myMethod //=> MyTrait::myMethod()
  }

  def myFunc(arg: Char): MyTrait = {
    arg match {
      case 'A' => new MyClassA
      case 'B' => new MyClassB
      case _ => new MyClass
    }
  }
}

trait MyTrait {
  def myMethod() {
    println("MyTrait::myMethod()")
  }
}

class MyClassA extends MyTrait {
  override def myMethod() {
    println("MyClassA::myMethod()")
  }
}

class MyClassB extends MyTrait {
  override def myMethod() {
    println("MyClassB::myMethod()")
  }
}

class MyClass extends MyTrait {
}

実行例

$ scalac trait.scala && scala Main
MyClassA::myMethod()
MyClassB::myMethod()
MyTrait::myMethod()
関連ページ
    インストール 2016-2-9 現在のところ Scala で YAML を扱うこなれた方法はないようです。ここでは SnakeYAML を利用します。 build.sbt (sbt) libraryDependencies += "org.yaml" % "snakeyaml" % "1.16" pom.xml (maven)
    ラムダ式 (Java 8) import java.util.Arrays; import java.util.List; import java.util.function.Function; class Main { public static String myFunc(Function<String, String> callback) { return cal