Scala之旅-使用mixins合成类

Scala之旅-使用mixins合成类

使用mixins合成类

Mixins就是被用来合成类的特征(traits)。

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
d.message  // I'm an instance of class B
d.loudMessage  // I'M AN INSTANCE OF CLASS B

类D有一个超类B和一个mixin C。类只能有一个超类,但是可以有很多mixins(分别使用关键字extendswith)。mixins和超类可以拥有相同的超类型(supertype)。

让我们再看一个更有趣的例子,首先是一个抽象类:

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,然后对这个String进行迭代操作(例如查看一个String中是否包含某个特定的字符)。

现在让我们创建一个特征,这个特征也是扩展自AbsIterator。

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

由于RichIterator是一个特征,所以它不需要实现AbsIterator的抽象成员。

下面我们将StringIterator和RichIterator的功能组合成一个单实例类。

object StringIteratorTest extends App {
  class Iter extends StringIterator(args(0)) with RichIterator
  val iter = new Iter
  iter foreach println
}

新类Iter有一个超类StringIterator和一个mixin RichIterator。

如果只能继承单个类,我们就无法实现这种级别的灵活性。

参考资料

本文译自Tour Of Scala – Class Composition with Mixins

上一篇:Scala之旅-特征

下一篇:Scala之旅-高阶函数

发表评论

电子邮件地址不会被公开。 必填项已用*标注