[译]Scala泛型类
2017-07-12 本文已影响296人
steanxy
泛型类是以一个类型作为参数的类。对于集合类特别有用。
定义泛型类
泛型类以一个类型作为参数,包含在[]中。试用字母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
重新分配到一个新列表中)。
用法
使用泛型类,使用具体的类型替换A。
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
println(stack.pop) // prints 2
println(stack.pop) // prints 1
stack
实例只能处理整数。但是,如果类型参数有子类型,则子类型也可以处理:
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
,所以我们可以在需要传入Fruit
类型实例的地方传入apple
和banana
实例。
注意:泛型的子类型是不可变的。意思是如果我们有一个Stack[Char],不能作为Stack[Int]使用。这是不合理的,因为那样我们就可以将整数放入字符型栈中。结论就是,Stack[A]只是Stack[B]的一个子类型,当且仅当B = A
。这个条件相当严格,所以Scala提供了type parameter annotation mechanism来控制泛型的子类型行为。