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()
0
Scalaはいいぞ
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。

