Scala之旅-泛型类

Scala之旅-泛型类

泛型类(Generic Classes)

泛型类是带有一个类型作为参数的类。泛型类对于集合类尤其有用。

定义一个泛型类

泛型类在[]中带有一个类型作为参数。惯例是使用字母A作为类型参数标识符,尽管任何参数名都是可以用的。

class Stack[A] {
  private var elements: List[A] = Nil
  def push(x: A) { elements = x :: elements }
  def peek: A = elements.head
  def pop(): A = {
    val currentTop = peek
    elements = elements.tail
    currentTop
  }
}

类Stack的实现以任意类型A作为参数。这意味着底层listvar elements: List[A] = Nil只能存储A类型的元素。def push只能接受A类型的对象(注意:elements = x :: elements将elements重新赋值给了一个新list,这个新list是通过把x加到当前elements的前面创建的)。

使用泛型类

要使用一个泛型类,就用类型代替A即可。

val stack = new Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop)  // prints 2
println(stack.pop)  // prints 1

实例stack只能使用Ints作为参数。然而,如果类型参数具有子类型,那些子类型也可以被传入:

class Fruit
class Apple extends Fruit
class Banana extends Fruit
val stack = new Stack[Fruit]
val apple = new Apple
val banana = new Banana
stack.push(apple)
stack.push(banana)

类Apple和Banana都扩展自Fruit,所以我们可以将实例apple和banana压入Fruit类型的stack。

注意:泛型类型的子类型是“不变的”。这意味着如果我们有一个字符stack:Stack[Char],则它不能被用作整数stack:Stack[Int]。这是不健全的,因为这使得我们将真正的整数放入字符stack。(This would be unsound because it would enable us to enter true integers into the character stack.)总结一下,当且仅当B = A时,Stack[A]才是Stack[B]的子类型。由于这会很有限制性,Scala提供了一个类型参数表示机制来控制泛型类型的子类型行为。

参考资料

本文译自Tour Of Scala – Generic Classes

上一篇:Scala之旅-For Comprehensions

下一篇:Scala之旅-变性

发表评论

电子邮件地址不会被公开。 必填项已用*标注