Upload
shuya-tsukamoto
View
70
Download
0
Embed Size (px)
Citation preview
初心者向けScala勉強会 Trait2015/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 <トレイト名> { // field, 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") }
field定義!
!
• fieldも定義可能
trait TraitA { val appName:String = "my-application" }
インスタンス生成時にmixintrait 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 fooconstructor traitA constructor traitB constructor barMain 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された)