抽象类型(例如特质和抽象类)反过来可以具有抽象类型成员。这意味着具体实现定义实际类型。这是一个示例
trait Buffer {
type T
val element: T
}
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
}
abstract class SeqBuffer extends Buffer:
type U
type T <: Seq[U]
def length = element.length
请注意,我们如何在 T
的上型界的规范中使用另一个抽象类型 U
。此 class SeqBuffer
允许我们仅将序列存储在缓冲区中,方法是声明类型 T
必须是新抽象类型 U
的 Seq[U]
的子类型。
具有抽象类型成员的特质或 类 通常与匿名类实例化结合使用。为了说明这一点,我们现在来看一个处理引用整数列表的序列缓冲区的程序
abstract class IntSeqBuffer extends SeqBuffer {
type U = Int
}
def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer =
new IntSeqBuffer {
type T = List[U]
val element = List(elem1, elem2)
}
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
abstract class IntSeqBuffer extends SeqBuffer:
type U = Int
def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer =
new IntSeqBuffer:
type T = List[U]
val element = List(elem1, elem2)
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
此处,工厂 newIntSeqBuf
使用 IntSeqBuffer
的匿名类实现(即 new IntSeqBuffer
)将抽象类型 T
设置为具体类型 List[Int]
。
还可以将抽象类型成员转换为类的类型参数,反之亦然。下面是仅使用类型参数的上述代码版本
abstract class Buffer[+T] {
val element: T
}
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
def length = element.length
}
def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] =
new SeqBuffer[Int, List[Int]] {
val element = List(e1, e2)
}
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
abstract class Buffer[+T]:
val element: T
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T]:
def length = element.length
def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] =
new SeqBuffer[Int, List[Int]]:
val element = List(e1, e2)
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
请注意,我们必须使用方差注解(+T <: Seq[U]
),以便隐藏从方法 newIntSeqBuf
返回的对象的具体序列实现类型。此外,在某些情况下,无法用类型参数替换抽象类型成员。