特征和抽象类可以有抽象类型的成员。这意味着实际的类型定义具体的实现。这里有一个例子:
trait Buffer {
type T
val element: T
}
这里我们定义了一个抽象 type T
。它被用来描述 element
的类型。我们能在抽象类中继承这个特征,添加 T
的类型上限让它更明确。
abstract class SeqBuffer extends Buffer {
type U
type T <: Seq[U]
def length = element.length
}
注意,我们使用另一个抽象 type U
作为类型上限。类 class SeqBuffer
允许我们只在缓冲区存储列表,类型 T
必须是新的抽象类型 U
的 Seq[U]
类的子类。
有抽象类型成员的特征或类经常与匿名类实例结合使用。为了演示它,我们现在来看一个处理指向整型列表的缓冲区序列程序:
abstract class IntSeqBuffer extends SeqBuffer {
type U = Int
}
def newIntSeqBuf(elem: Int, elem2: Int): IntSeqBuffer =
new IntBuffer {
type T = List[U]
val element = List(elem1, elem2)
}
val buf = newIntBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
这里的 newIntSeqBuf
工厂使用一个匿名类实现 IntSeqBuf
,设置 type T
为 List[Int]
。
也可以将抽象类型成员变成类的类型参数。下面这个例子的代码只使用了类型参数:
abstract class Buffer[+T] {
val element: T
}
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffe[T] {
def length = element.length
}
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
注意:在这里使用 变化注解(+T <: Seq[U]
)是为了隐藏从 newIntSeqBuf
方法中返回的对象的具体序列实现类型。此外,有些情况下无法将类型参数转换成抽象类型。