scala之旅-核心语言特性【泛型类】(十九)

泛型类是指传递类型作为形参的类。在集合类中用的比较多。

定义泛型类

泛型类用中括号传递一个形参。约定用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提供了一种类型参数注解机制来控制泛型的子类型行为。

posted @ 2020-11-04 11:17  周周周文阳  阅读(79)  评论(0编辑  收藏  举报