1. 程式人生 > 實用技巧 >scala之旅-核心語言特性【使用混入組合類】(九)

scala之旅-核心語言特性【使用混入組合類】(九)

混入是特性常用的手段用來構建一個類

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) extends
AbsIterator { 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 抽象類的抽象方法】