混合就是被用來組合成類的特徵。
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
需要一個字符串參數用來迭代字符。
現在,讓我們創建一個特徵也繼承 AbsIterator
。
trait RichIterator extends AbsIterator {
def foreach(f: T => Unit): Unit = while (hasNext) f(next())
}
因爲 RichIterator
是特徵,所以不需要實現抽象類 AbsIterator
中的方法。
現在,我們將 StringIterator
類和 RichIterator
特徵的功能組合成一個簡單的類中。
object StringIteratorTest extends App {
class RichStringIter extends StringIterator("Scala") with RichIterator
val richStringIter = new RichStringIter
richStringIter foreach println
}
新的類 RichStringIter
父類爲 StringIterator
還混合了 RichIterator
特徵。
這是我們使用簡單的繼承不能實現這種程度的複雜功能。