专栏原创出处:github-源笔记文件 (opens new window) ,github-源码 (opens new window),欢迎 Star,转载请附上原文出处链接和本声明。
Scala 编程语言专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Scala 编程语言 (opens new window)
# 什么是抽象类型
特质和抽象类可以包含一个抽象类型成员,由 type
关键字定义,实际类型可以在具体实现类中定义。
trait Buffer {
type T // 抽象类型,是用来描述成员 element 的类型的
val element: T
}
abstract class SeqBuffer extends Buffer {
type U // 另外一个抽象类型来限定上边界
type T <: Seq[U] // 声明类型 T 只能是 Seq[U] 的子类,这个 SeqBuffer 就限定的元素只能是序列
def length = element.length
}
abstract class IntSeqBuffer extends SeqBuffer {
type U = Int
}
// 使用了 IntSeqBuffer 的匿名类实现方式
def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer =
new IntSeqBuffer {
type T = List[U] // 类型 T 被设置成了 List[Int]
val element = List(elem1, elem2)
}
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length) // length = 2
println("content = " + buf.element) // content = List(7, 8)
# 抽象类型转换成类型参数
把抽象类型成员转成类的类型参数
也是可行的。
有些情况下用类型参数替换抽象类型是行不通的。
// 本示例只用了类的类型参数来转换上面的示例,效果是相同的。
abstract class Buffer[+T] {
val element: T
}
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
def length = element.length
}
// 为了隐藏该方法返回的具体序列实现类型 SeqBuffer[Int, List[Int]]
// SeqBuffer 的类型参数+T <: Seq[U] 应将 T 类型定义为协变
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)