122.md 3.8 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4 5 6
# 泛型,继承和子类型

> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html](https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html)

如您所知,只要类型兼容,就可以将一种类型的对象分配给另一种类型的对象。例如,您可以将`整数`分配给`对象`,因为`对象``整数`的超类型之一:

W
wizardforcel 已提交
7
```java
W
init  
wizardforcel 已提交
8 9 10 11 12 13
Object someObject = new Object();
Integer someInteger = new Integer(10);
someObject = someInteger;   // OK

```

W
wizardforcel 已提交
14
在面向对象的术语中,这被称为“是一种”关系。由于`整数` _ 是*`对象`,因此允许分配。但是`Integer`也是一种`Number` ,所以下面的代码也是有效的:
W
init  
wizardforcel 已提交
15

W
wizardforcel 已提交
16
```java
W
init  
wizardforcel 已提交
17 18 19 20 21 22 23
public void someMethod(Number n) { /* ... */ }

someMethod(new Integer(10));   // OK
someMethod(new Double(10.1));   // OK

```

W
wizardforcel 已提交
24
仿制药也是如此。您可以执行泛型类型调用,将`Number`作为其类型参数传递,如果参数与`Number`兼容,则允许`add`的任何后续调用:
W
init  
wizardforcel 已提交
25

W
wizardforcel 已提交
26
```java
W
init  
wizardforcel 已提交
27 28 29 30 31 32 33 34
Box<Number> box = new Box<Number>();
box.add(new Integer(10));   // OK
box.add(new Double(10.1));  // OK

```

现在考虑以下方法:

W
wizardforcel 已提交
35
```java
W
init  
wizardforcel 已提交
36 37 38 39
public void boxTest(Box<Number> n) { /* ... */ }

```

W
wizardforcel 已提交
40
它接受什么类型的论据?通过查看其签名,您可以看到它接受一个类型为`Box&lt; Number&gt;的参数。` 。但是,这是什么意思?您是否可以通过`Box&lt; Integer>``Box&lt; Double>` ,正如您所料?答案是“不”,因为`Box&lt; Integer>``Box&lt; Double>`不是`Box&lt; Number&gt;的亚型。`
W
init  
wizardforcel 已提交
41 42 43

在使用泛型编程时,这是一个常见的误解,但这是一个需要学习的重要概念。

W
wizardforcel 已提交
44
![diagram showing that Box<Integer> is not a subtype of Box<Number>](img/4953ad914ddbdaec1fe145e50985a7d2.jpg)
W
init  
wizardforcel 已提交
45

W
wizardforcel 已提交
46
`Box<Integer>` is not a subtype of `Box<Number>` even though `Integer` is a subtype of `Number`.
W
init  
wizardforcel 已提交
47 48 49 50 51 52 53 54 55

* * *

**Note:** Given two concrete types `A` and `B` (for example, `Number` and `Integer`), `MyClass<A>` has no relationship to `MyClass<B>`, regardless of whether or not `A` and `B` are related. The common parent of `MyClass<A>` and `MyClass<B>` is `Object`.

For information on how to create a subtype-like relationship between two generic classes when the type parameters are related, see [Wildcards and Subtyping](subtyping.html).

* * *

W
wizardforcel 已提交
56
您可以通过扩展或实现泛型类或接口来对其进行子类型化。一个类或接口的类型参数与另一个类型参数的类型参数之间的关系由`extends``实现`子句确定。
W
init  
wizardforcel 已提交
57

W
wizardforcel 已提交
58
使用`集合`类作为示例, `ArrayList&lt; E>`实现`List&lt; E>``列表&lt; E&gt; extends Collection&lt; E>` 。所以`ArrayList&lt; String>``List&lt; String&gt;的子类型。` ,它是`Collection&lt; String&gt;的子类型。` 。只要不改变类型参数,就会在类型之间保留子类型关系。
W
init  
wizardforcel 已提交
59

W
wizardforcel 已提交
60
![diagram showing a sample collections hierarchy: ArrayList<String> is a subtype of List<String>, which is a subtype of Collection<String>.](img/53a7bba39584accc105f76c8b7af56b3.jpg)
W
init  
wizardforcel 已提交
61

W
wizardforcel 已提交
62
A sample `Collections` hierarchy
W
init  
wizardforcel 已提交
63

W
wizardforcel 已提交
64
现在假设我们想要定义我们自己的列表接口, `PayloadList` ,它将泛型类型`P`的可选值与每个元素相关联。它的声明可能如下:
W
init  
wizardforcel 已提交
65

W
wizardforcel 已提交
66
```java
W
init  
wizardforcel 已提交
67 68 69 70 71 72 73
interface PayloadList<E,P> extends List<E> {
  void setPayload(int index, P val);
  ...
}

```

W
wizardforcel 已提交
74
`PayloadList`的以下参数化是`List&lt; String&gt;的子类型。`
W
init  
wizardforcel 已提交
75

W
wizardforcel 已提交
76 77 78
*   `PayloadList&lt; String,String>`
*   `PayloadList&lt; String,Integer>`
*   `PayloadList&lt; String,Exception>`
W
init  
wizardforcel 已提交
79

W
wizardforcel 已提交
80
![diagram showing an example PayLoadList hierarchy: PayloadList<String, String> is a subtype of List<String>, which is a subtype of Collection<String>. At the same level of PayloadList<String,String> is PayloadList<String, Integer> and PayloadList<String, Exceptions>.](img/4ba0deb28efaf72ab893f651aff1a11b.jpg)
W
init  
wizardforcel 已提交
81

W
wizardforcel 已提交
82
A sample `PayloadList` hierarchy