File tree Expand file tree Collapse file tree 1 file changed +45
-1
lines changed Expand file tree Collapse file tree 1 file changed +45
-1
lines changed Original file line number Diff line number Diff line change 1
1
---
2
2
layout : tour
3
- title : Generic Classes
3
+ title : 泛型类
4
4
5
5
discourse : false
6
6
@@ -13,3 +13,47 @@ language: zh-cn
13
13
next-page : variances
14
14
previous-page : extractor-objects
15
15
---
16
+ 泛型类指可以接受类型参数的类。泛型类在集合类中被广泛使用。
17
+
18
+ ## 定义一个泛型类
19
+ 泛型类使用方括号 ` [] ` 来接受类型参数。一个惯例是使用字母 ` A ` 作为参数标识符,当然你可以使用任何参数名称。
20
+ ``` tut
21
+ class Stack[A] {
22
+ private var elements: List[A] = Nil
23
+ def push(x: A) { elements = x :: elements }
24
+ def peek: A = elements.head
25
+ def pop(): A = {
26
+ val currentTop = peek
27
+ elements = elements.tail
28
+ currentTop
29
+ }
30
+ }
31
+ ```
32
+ 上面的 ` Stack ` 类的实现中接受类型参数 ` A ` 。 这表示其内部的列表,` var elements: List[A] = Nil ` ,只能够存储类型 ` A ` 的元素。方法 ` def push ` 只接受类型 ` A ` 的实例对象作为参数(注意:` elements = x :: elements ` 将 ` elements ` 放到了一个将元素 ` x ` 添加到 ` elements ` 的头部而生成的新列表中)。
33
+
34
+ ## 使用
35
+
36
+ 要使用一个泛型类,将一个具体类型放到方括号中来代替 ` A ` 。
37
+ ```
38
+ val stack = new Stack[Int]
39
+ stack.push(1)
40
+ stack.push(2)
41
+ println(stack.pop) // prints 2
42
+ println(stack.pop) // prints 1
43
+ ```
44
+ 实例对象 ` stack ` 只能接受整型值。然而,如果类型参数有子类型,子类型可以被传入:
45
+ ```
46
+ class Fruit
47
+ class Apple extends Fruit
48
+ class Banana extends Fruit
49
+
50
+ val stack = new Stack[Fruit]
51
+ val apple = new Apple
52
+ val banana = new Banana
53
+
54
+ stack.push(apple)
55
+ stack.push(banana)
56
+ ```
57
+ 类 ` Apple ` 和类 ` Banana ` 都继承自类 ` Fruit ` ,所以我们可以把实例对象 ` apple ` 和 ` banana ` 压入栈 ` Fruit ` 中。
58
+
59
+ _ 注意:泛型类型的子类型是* 不可传导* 的。这表示如果我们有一个字母类型的栈 ` Stack[Char] ` ,那它不能被用作一个整型的栈 ` Stack[Int] ` 。否则就是不安全的,因为它将使我们能够在字母型的栈中插入真正的整型值。结论就是,只有当类型 ` B = A ` 时, ` Stack[A] ` 是 ` Stack[B] ` 的子类型才成立。因为此处可能会有很大的限制,Scala 提供了一种 [ 类型参数注释机制] ( variances.html ) 用以控制泛型类型的子类型的行为。_
You can’t perform that action at this time.
0 commit comments