泛型类是以一个类型作为参数的类。对于集合类特别有用。
定义泛型类
泛型类以一个类型作为参数,包含在[]中。试用字母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来控制泛型的子类型行为。
本文介绍了Scala中的泛型类概念及其实现方式。通过定义泛型类,可以创建以类型为参数的类,这对于集合类非常有用。文章还提供了一个Stack泛型类的例子,并展示了如何使用具体的类型替换类型参数。
99

被折叠的 条评论
为什么被折叠?



