狠狠撸

狠狠撸Share a Scribd company logo
初心者向けScala勉強会
Trait
2015/02/10
!
Shuya Tsukamoto
Trait
? trait?
【名】特徴、特質
? 出自?
Nathanael Sch?rli, Stéphane Ducasse, Oscar Nierstrasz, and Andrew P. Black. Traits:
Composable Units of Behavior. Technical Report -2, Institut für Informatik, Universit?t Bern,
Switzerland, November 2002
? メソッド、フィールドの定義をまとめたもの
基本構文
!
!
? trait <トレイト名> {?
// ?eld, method?
}
trait TraitA {
def printData():Unit
}
使い方
trait TraitA {
def printData():Unit
}
!
object Main extends TraitA {
def main(args: Array[String]):Unit = {
println("Main start.")
printData()
println("Main end.")
}
!
override def printData(): Unit = println("traitA")
}
使い方
trait TraitA {
def printData():Unit
}
!
object Main extends TraitA {
def main(args: Array[String]):Unit = {
println("Main start.")
printData()
println("Main end.")
}
!
override def printData(): Unit = println("traitA")
}
1. extendsする
2. 未定義のメンバは定義する
2つ以上の場合
object Main extends TraitA with TraitB {
!
? withで繋げる
? TraitAもtraitだけど、これはextends?
最低1つ「extends」が必要
デフォルト実装
!
!
? mixinした側で定義する必要なし
trait TraitA {
def printData(): Unit = println("traitA")
}
?eld定義
!
!
? ?eldも定義可能
trait TraitA {
val appName:String = "my-application"
}
インスタンス生成時にmixin
trait TraitA {
val appName: String = "my-application"
}
!
class Foo
!
object Main {
def main(args: Array[String]): Unit = {
println("Main start.")
!
val foo = new Foo with TraitA
println(foo.appName)
!
println("Main end.")
}
}
コンストラクタは左から
trait TraitA { println("constructor traitA") }
trait TraitB { println("constructor traitB") }
class SuperFoo { println("constructor foo") }
class SubBar extends SuperFoo { println("constructor bar") }
!
class Hoge extends SubBar with TraitA with TraitB
!
object Main {
def main(args: Array[String]): Unit = {
println("Main start.")
val hoge = new Hoge
println("Main end.")
}
} // start, foo, bar, traitA, traitB, end
traitの順番
!
!
!
? もしもHogeよりも上位であるSuperFooで既にwith
されていたら?
trait TraitA { println("constructor traitA") }
trait TraitB { println("constructor traitB") }
class SuperFoo { println("constructor foo") }
class SubBar extends SuperFoo with TraitA with TraitB
{ println("constructor bar") }
!
class Hoge extends SubBar with TraitA with TraitB
traitの順番
? Main start.?
constructor foo?
constructor traitA?
constructor traitB?
constructor bar?
Main end.
? barの後で初期化は走らず
traitの処理変更
trait Sort {
def sort(seq: Seq[Long]) = seq.sortWith(_ < _)
}
trait ReverseSortStrategy extends Sort {
override def sort(seq: Seq[Long]) = seq.sortWith(_ > _)
}
!
class Foo extends Sort
object Main extends App {
val numbers = Seq[Long](5, 2, 8)
val foo = new Foo
println(foo.sort(numbers)) //2,5,8
val foo2 = new Foo with ReverseSortStrategy
println(foo2.sort(numbers)) //8,5,2
}
traitの処理変更
? withの有無で処理が変わる
traitの処理変更
trait Sort {
def sort(seq: Seq[Long]) = seq.sortWith(_ < _)
}
trait ReverseSortStrategy extends Sort {
override def sort(seq: Seq[Long]) = seq.sortWith(_ > _)
}
trait BugSortStrategy extends Sort {
override def sort(seq: Seq[Long]) = seq.map(_ * 100)
}
class Foo extends Sort
object Main extends App {
val numbers = Seq[Long](5, 2, 8)
val foo = new Foo with ReverseSortStrategy with
BugSortStrategy
println(foo.sort(numbers)) //500,200,800
}
traitの処理変更
? withの有無で処理が変わる
? constructorは左から、でも処理は右から?
(左から定義されていって最終的に右のもので
overrideされた)

More Related Content

Scala勉強会 2015 02_03