泛型类是指传递类型作为形参的类。在集合类中用的比较多。
定义泛型类
泛型类用中括号传递一个形参。约定用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作为形参。这表示在组成列表中, var elements: List[A] = Nil 只能存储类型 A。 方法 def push 只接受A类型的参数。(注意,elements = x :: elements 是在当前的 elements 前面添加一个 x,然后重新赋值给elements)
Nil 这里是一个空的list,注意不要跟null 混淆
语法
使用一个泛型类,将一个类型放入到中括号里面代替类型A.
val stack = new Stack[Int] stack.push(1) stack.push(2) println(stack.pop) // prints 2 println(stack.pop) // prints 1
实例stack 只能使用Int类型。但是,如果实参类型有子类型,这也是同样可以的。
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 推送到 Stack[Fruit]中。
注意: 有子类型的泛型是"不变的"。这意味着如果有一个 char类型修饰的stack如 Stack[Char] ,它是不能被用作整型的stack Stack[Int]中的。这是不合理的,因为它会导致我们在 char类型的Stack中输入 Int型的数据。 结论就是 当且仅当 B=A且A是B的子类型时才满足条件。由于这可能非常严格,因此Scala提供了一种类型参数注解机制来控制泛型的子类型行为。