Scala之旅(TOUR OF SCALA)——泛型类(Generic Classes)

泛型类是一种带了一个类型作为参数的类。他们对集合类是非常有用的。

定义一个泛型类(Defining a generic class)

泛型类使用中括号 [] 接收类型参数,虽然类型参数可以是任何名字,但是一个惯例是使用字母 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)。

使用(Usage)

为了使用泛型类,我们需要使用一个具体的类来代替中括号中的 A

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

实例 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 类的子类,所以我们可以将 AppleBanana 的实例压入 Fruit 类型的栈中。

注意:泛型类型中的子类型是不变的(invariant)。这意味着如果我们有一个字符类型的栈 Stack[Char],那我们不能作为一个整型的栈 Stack[Int] 来使用。这是不安全的,因为它可以使我们输入真正的整数到字符栈中。总之,当且仅当 B = A 时,Stack [A] 只能是 Stack [B] 的一个子类型。这可能是相当严格的,所以 Scala 提供了一种类型参数注释机制 来控制泛型类中子类型的行为。

Guess you like

Origin blog.csdn.net/cuipp0509/article/details/80250463