16
初心者向けScala勉強会 Trait 2015/02/10 Shuya Tsukamoto

Scala勉強会 2015 02_03

Embed Size (px)

Citation preview

Page 1: Scala勉強会 2015 02_03

初心者向けScala勉強会 Trait2015/02/10

!Shuya Tsukamoto

Page 2: Scala勉強会 2015 02_03

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

• メソッド、フィールドの定義をまとめたもの

Page 3: Scala勉強会 2015 02_03

基本構文!

!

• trait <トレイト名> { // field, method}

trait TraitA { def printData():Unit }

Page 4: Scala勉強会 2015 02_03

使い方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") }

Page 5: Scala勉強会 2015 02_03

使い方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. 未定義のメンバは定義する

Page 6: Scala勉強会 2015 02_03

2つ以上の場合object Main extends TraitA with TraitB {

!

• withで繋げる

• TraitAもtraitだけど、これはextends 最低1つ「extends」が必要

Page 7: Scala勉強会 2015 02_03

デフォルト実装!

!

• mixinした側で定義する必要なし

trait TraitA { def printData(): Unit = println("traitA") }

Page 8: Scala勉強会 2015 02_03

field定義!

!

• fieldも定義可能

trait TraitA { val appName:String = "my-application" }

Page 9: Scala勉強会 2015 02_03

インスタンス生成時に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.") } }

Page 10: Scala勉強会 2015 02_03

コンストラクタは左から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

Page 11: Scala勉強会 2015 02_03

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

Page 12: Scala勉強会 2015 02_03

traitの順番• Main start.constructor fooconstructor traitA constructor traitB constructor barMain end.

• barの後で初期化は走らず

Page 13: Scala勉強会 2015 02_03

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 }

Page 14: Scala勉強会 2015 02_03

traitの処理変更• withの有無で処理が変わる

Page 15: Scala勉強会 2015 02_03

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 }

Page 16: Scala勉強会 2015 02_03

traitの処理変更• withの有無で処理が変わる

• constructorは左から、でも処理は右から(左から定義されていって最終的に右のものでoverrideされた)