专栏原创出处: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)
最后修改时间: 2/17/2020, 4:43:04 AM