简体   繁体   English

Java通用参数和继承

[英]Java generic parameters and inheritance

supposed we know that ViewGroup extends View. 假设我们知道ViewGroup扩展了View。
Further we have a generic, parametrized class A<T extends View> 此外,我们有一个通用的,参数化的class A<T extends View>

Question: 题:
Why wont method C.add() accept new A<ViewGroup>() as parameter? 为什么方法C.add()接受new A<ViewGroup>()作为参数?
Shouldn't it work, because of polymorphism? 由于多态性,它不行吗?

类图

SOLUTION: Singning add with ? extends View 解决方案:唱歌加? extends View ? extends View lets add accept new A<ViewGroup>() as a parameter. ? extends View可以添加接受new A<ViewGroup>()作为参数。

解

You signed your add method as: 您将add方法签名为:

static void add(A<View>)

but you probably meant: 但是您可能的意思是:

static void add(A<? extends View> a)

Not quite because add() might be using a method of View that is not found in ViewGroup . 不太完全是因为add()可能正在使用ViewGroup找不到的View方法。

Summary: View is a ViewGroup , however ViewGroup is not a View . 摘要: ViewViewGroup ,但是ViewGroup不是View Polymorphism is where you can assign a View object to a ViewGroup declaration. 多态是您可以将View对象分配给ViewGroup声明的地方。

First of all, your question isn't very clear because the UML diagram contradicts your text. 首先,您的问题不是很清楚,因为UML图与您的文本矛盾。 You say that View extends ViewGroup, but the diagram shows the reverse : ViewGroup extends View. 您说View扩展了ViewGroup,但是该图显示了相反的内容:ViewGroup扩展了View。

Now, a List<Car> doesn't extend a List<Vehicle> . 现在, List<Car>不会扩展List<Vehicle> If it were the case, you could do: 如果是这样,您可以执行以下操作:

List<Car> listOfCars = new ArrayList<Car>();
List<Vehicle> listOfVehicles = listOfCars;
listOfVehicles.add(new Bicycle());
// now the list of cars contain a bicycle. Not pretty. 

First of all you said View extends ViewGroup, but the diagram says ViewGroup extends View (which I assume to be right). 首先,您说View扩展了ViewGroup,但图中显示ViewGroup扩展了View(我认为是正确的)。

Secondly, you are not allowed to pass a List<ViewGroup> as a List<View> . 其次,不允许将List<ViewGroup>作为List<View>传递。 This is a compile time protection to prevent someone from adding an AnotherView into this list and compromise type-safety of generics. 这是一种编译时保护,可以防止某人将AnotherView添加到此列表中并损害泛型的类型安全性。

List<ViewGroup> is not a subtype of List<View> , but it is a subtype of List<? extends View> List<ViewGroup>不是List<View>的子类型,但是它是List<? extends View>的子类型List<? extends View> List<? extends View> . List<? extends View> So you can modify your method to accept a List<? extends View> 因此,您可以修改您的方法以接受List<? extends View> List<? extends View> instead, but be aware that you can't add to the list passed to the method this way. 而是改为List<? extends View> ,但要注意,您不能以这种方式添加到传递给该方法的列表中。

There is also another syntax called lower bound wildcard ( List<? super ViewGroup> ), as opposed to the upper bound wildcard mentioned above, which enables you to add to the list but you can olny pass in a list of ViewGroup or its parents. 与上面提到的上限通配符相反,还有另一种语法称为下限通配符( List<? super ViewGroup> ),它使您可以添加到列表中,但可以通过任何方式传入ViewGroup或其父级列表。

More about wildcards in generics can be found here: http://download.oracle.com/javase/tutorial/java/generics/wildcards.html 有关泛型通配符的更多信息,请参见: http : //download.oracle.com/javase/tutorial/java/generics/wildcards.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM