scala之旅-核心語言特性【使用混入組合類】(九)
阿新 • • 發佈:2020-10-26
混入是特性常用的手段用來構建一個類
abstract class A { val message: String } class B extends A { val message = "I'm an instance of class B" } trait C extends A { def loudMessage = message.toUpperCase() } class D extends B with C val d = new D println(d.message) // I'm an instance of class B println(d.loudMessage) //I'M AN INSTANCE OF CLASS B
類 D 有一個超類B 和一個混入特性C。類只能有一個超類但是可以有多個混入(分別使用 extends和with 關鍵字)。混入和超類擁有相同的超型別。
現在讓我們看一個從抽象類開始的更有趣的示例:
abstract class AbsIterator { type T def hasNext: Boolean def next(): T }
這個類有一個抽象的型別 T,和一個標準的迭代器方法 。
然後我們將實現一個具體的類(所有的抽象成員包括 T,hasNext和 next 都將被實現)
class StringIterator(s: String) extendsAbsIterator { type T = Char private var i = 0 def hasNext = i < s.length def next() = { val ch = s charAt i i += 1 ch } }
StringIterator 傳遞類一個 String ,並且可用於遍歷字串 (檢視一個字串是否包含某個字元)
現在,讓我們建立一個也可以擴充套件的特徵AbsIterator
。
trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while(hasNext) f(next()) }
這個特性通過連續地在下個節點 ( next()) 呼叫 f:T => Unit 實現 foreach迴圈,只要還有下一個節點 (while(hasNext)) 還有。因為RichIterator 是一個特性,所以它不需要實現 AbsIterator 的抽象成員。
我們更多的會用功能齊全的StringIterator 類和RichIterator 組合成一個單獨的類
class RichStringIter extends StringIterator("Scala") with RichIterator val richStringIter = new RichStringIter richStringIter.foreach(println)
這個新類RichStringIter 有一個StringIterator 超類,以及一個 RichIterator 作為一個混合。
使用單繼承,我們是無法做到這樣的靈活性的。
【注:本章著重介紹的是特性的使用。特性可以宣告抽象,又可以實現抽象。相當於java8中的介面,使用default 的方式override 抽象類的抽象方法】