Skip to content

Commit a290146

Browse files
committed
通配符和继承
1 parent fc997ca commit a290146

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
* [断言](ch01/05_Assertions.md#断言)
2727
* [第二章(子类型化和通配符)](ch02/00_Subtyping_and_Wildcards.md#第二章(子类型化和通配符))
2828
* [子类型化和替代原则](ch02/01_Subtyping_and_the_Substitution_Principle.md#子类型化和替代原则)
29+
* [通配符和继承](ch02/02_Wildcards_with_extends.md#通配符和继承)
30+
2931
---
3032

3133
![Java Generics and Collections](book.jpg)

SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
* [泛型方法和可变参数](ch01/04_Generic_Methods_and_Varargs.md#泛型方法和可变参数)
1717
* [断言](ch01/05_Assertions.md#断言)
1818
* [第二章(子类型化和通配符)](ch02/00_Subtyping_and_Wildcards.md#第二章(子类型化和通配符))
19-
* [子类型化和替代原则](ch02/01_Subtyping_and_the_Substitution_Principle.md#子类型化和替代原则)
19+
* [子类型化和替代原则](ch02/01_Subtyping_and_the_Substitution_Principle.md#子类型化和替代原则)
20+
* [通配符和继承](ch02/02_Wildcards_with_extends.md#通配符和继承)

ch02/02_Wildcards_with_extends.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
《《《 [返回首页](../README.md)
2+
3+
### 通配符和继承
4+
5+
- `Collection`接口中的另一个方法是`addAll`,它将一个集合的所有成员添加到另一个集合中:
6+
7+
```java
8+
interface Collection<E> {
9+
...
10+
public boolean addAll(Collection<? extends E> c);
11+
...
12+
}
13+
```
14+
- 显然,给定`E`类型的元素的集合,可以将另一个集合的所有成员添加到`E`类型的元素中。
15+
这个古怪的短语`? extends E`意味着也可以添加元素任何类型都是`E`的子类型的所有成员 。
16+
问号称为通配符,因为它代表某种类型,它是`E`的子类型。
17+
18+
- 这是一个例子。 我们创建一个空的数字列表,并首先添加一个整数列表,
19+
然后是一个双精度列表:
20+
21+
```java
22+
List<Number> nums = new ArrayList<Number>();
23+
List<Integer> ints = Arrays.asList(1, 2);
24+
List<Double> dbls = Arrays.asList(2.78, 3.14);
25+
nums.addAll(ints);
26+
nums.addAll(dbls);
27+
assert nums.toString().equals("[1, 2, 2.78, 3.14]");
28+
```
29+
30+
- 第一个调用是允许的,因为`nums`的类型是`List<Number>`,它是`Collection<Number>`的子类型,
31+
`ints`的类型是`List<Integer>`,它是`Collection`的子类型`Collection<? extends Number>`
32+
第二个调用同样被允许。 在这两个调用中,`E`被认为是`Number`。 如果`addAll`的方法签名没有使用通配符,
33+
那么将不允许添加整数列表和双精度列表的调用; 你只能添加一个明确声明为数字列表的列表。
34+
35+
- 声明变量时我们也可以使用通配符。 下面是上一节末尾的示例变体,通过在第二行添加通配符进行更改:
36+
37+
```java
38+
List<Integer> ints = new ArrayList<Integer>();
39+
ints.add(1);
40+
ints.add(2);
41+
List<? extends Number> nums = ints;
42+
nums.add(3.14); // 编译报错
43+
assert ints.toString().equals("[1, 2, 3.14]"); // uh oh!
44+
```
45+
- 之前,第四行导致了一个编译时错误(因为`List<Integer>`不是`List<Number>`的子类型),
46+
但是第五行没有问题(因为`double`是一个数字,所以你可以添加一个`double`到一个`List<Number>`)。
47+
现在,第四行是正确的(因为`List<Integer>``List<? extends Number>`的子类型),
48+
但是第五行会导致编译时错误(因为您不能将一个`double`添加到`List<? extends Number>`
49+
因为它可能是一些其他的数字子类型的列表)。 和以前一样,最后一行显示为什么之前的行是非法的!
50+
51+
- 一般来说,如果一个结构包含一个表单类型的元素? 扩展`E`,我们可以从结构中获得元素,
52+
但是我们不能将元素放入结构中。 为了将元素放入结构中,我们需要使用另一种通配符,
53+
如下一节所述。
54+
55+
56+
《《《 [返回首页](../README.md)

0 commit comments

Comments
 (0)