Scala中的术语mixin是指若干trait,这些trait可以用于合成一个类。同样的,为免误导大家,我并不打算翻译mixin,大家可以直接通过mixin这个单词来领会Scala用其想要表达的意思。
// 抽象类A,包含一个字符串类型的成员属性message
abstract class A {
val message: String
}
// 类B继承A,并定义了具体定义了属性message的值
class B extends A {
val message = "I'm an instance of class B"
}
// trait C继承A,添加了一个loudMessage方法
trait C extends A {
def loudMessage = message.toUpperCase()
}
// 类D继承B并实现C
class D extends B with C
// 实例化一个D
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。Scala不支持多继承,也就是说一个类只能有一个父类。但可以有多个mixin。继承一个类使用extends
关键词,扩展一个mixin使用with
关键词。
abstract class AbsIterator {
type T
def hasNext: Boolean
def next(): T
}
上面的抽象类AbsIterator含有一个抽象的(未特别指定的)类型T和标准的迭代方法。
然后,我们通过将抽象类型T和迭代方法具体化来实现一个具体的类。
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 。StringIterator 类的构造器接收一个String类型参数。其中,抽象类型T被具体指定为Char类型,迭代方法hasNext和next也都有了具体的定义,另外定义了一个私有成员i,用于指示迭代到了字符串的第几个字符。这样,StringIterator类便可以用于迭代一个字符串了。
下面,我们再创建一个trait,同样继承自AbsIterator。
trait RichIterator extends AbsIterator {
def foreach(f: T => Unit): Unit = while (hasNext) f(next())
}
RichIterator是一个trait,它并不需要实现AbsIterator中的抽象方法。
我们想要将StringIterator 和 RichIterator的功能合成到一个类中:
object StringIteratorTest extends App {
class RichStringIter extends StringIterator(args(0)) with RichIterator
val rsiter= new RichStringIter
rsiter foreach println
}
新的类RichStringIter有一个父类StringIterator,还有一个mixin RichIterator。