Scala 游览

使用 Mixin 进行类组合

语言

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(分别使用关键字 extendswith)。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 和标准迭代器方法。

接下来,我们将实现一个具体类(所有抽象成员 ThasNextnext 都有实现)

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())
}

此特质通过在下一个元素(next())上连续调用提供的函数 f: T => Unit 来实现 foreach,只要有更多元素(while (hasNext))。由于 RichIterator 是一个特质,因此它不需要实现 AbsIterator 的抽象成员。

trait RichIterator extends AbsIterator:
  def foreach(f: T => Unit): Unit = while hasNext do f(next())

此特质通过在下一个元素(next())上连续调用提供的函数 f: T => Unit 来实现 foreach,只要有更多元素(while hasNext)。由于 RichIterator 是一个特质,因此它不需要实现 AbsIterator 的抽象成员。

我们希望将 StringIteratorRichIterator 的功能组合到一个类中。

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)

新类 RichStringIterStringIterator 为超类,以 RichIterator 为混合类。

使用单一继承,我们无法实现这种灵活性。

此页面的贡献者