Mixin 是用於組合類別的特質。
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
和 mixin C
。類別只能有一個超級類別,但可以有多個 mixin(分別使用關鍵字 extends
和 with
)。Mixin 和超級類別可以有相同的超類別。
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, C
val d = D()
println(d.message) // I'm an instance of class B
println(d.loudMessage) // I'M AN INSTANCE OF CLASS B
類別 D
有超級類別 B
和 mixin C
。類別只能有一個超級類別,但可以有多個 mixin(分別使用關鍵字 extends
和分隔符號 ,
)。Mixin 和超級類別可以有相同的超類別。
現在讓我們來看一個從抽象類別開始的更有趣的範例
abstract class AbsIterator {
type T
def hasNext: Boolean
def next(): T
}
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
}
}
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
,可用於在 String 上進行迭代(例如,查看 String 是否包含某個字元)。
現在讓我們建立一個特質,它也延伸 AbsIterator
。
trait RichIterator extends AbsIterator {
def foreach(f: T => Unit): Unit = while (hasNext) f(next())
}
這個特質透過持續呼叫提供的函式 f: T => Unit
來實作 foreach
,只要有進一步的元素(while (hasNext)
),就會在下一元素(next()
)上呼叫它。因為 RichIterator
是特質,所以它不需要實作 AbsIterator 的抽象成員。
trait RichIterator extends AbsIterator:
def foreach(f: T => Unit): Unit = while hasNext do f(next())
此特質透過持續呼叫提供的函數 f: T => Unit
來實作 foreach
,只要有進一步的元素(while hasNext
),就會在下一元素(next()
)上執行。由於 RichIterator
是特質,因此它不需要實作 AbsIterator 的抽象成員。
我們想要將 StringIterator
和 RichIterator
的功能結合到單一類別中。
class RichStringIter extends StringIterator("Scala") with RichIterator
val richStringIter = new RichStringIter
richStringIter.foreach(println)
class RichStringIter extends StringIterator("Scala"), RichIterator
val richStringIter = RichStringIter()
richStringIter.foreach(println)
新的類別 RichStringIter
使用 StringIterator
作為超類別,並使用 RichIterator
作為混入。
使用單一繼承,我們無法達到這種程度的彈性。