繁体   English   中英

Java通用参数和继承

[英]Java generic parameters and inheritance

假设我们知道ViewGroup扩展了View。
此外,我们有一个通用的,参数化的class A<T extends View>

题:
为什么方法C.add()接受new A<ViewGroup>()作为参数?
由于多态性,它不行吗?

类图

解决方案:唱歌加? extends View ? extends View可以添加接受new A<ViewGroup>()作为参数。

解

您将add方法签名为:

static void add(A<View>)

但是您可能的意思是:

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

不太完全是因为add()可能正在使用ViewGroup找不到的View方法。

摘要: ViewViewGroup ,但是ViewGroup不是View 多态是您可以将View对象分配给ViewGroup声明的地方。

首先,您的问题不是很清楚,因为UML图与您的文本矛盾。 您说View扩展了ViewGroup,但是该图显示了相反的内容:ViewGroup扩展了View。

现在, List<Car>不会扩展List<Vehicle> 如果是这样,您可以执行以下操作:

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

首先,您说View扩展了ViewGroup,但图中显示ViewGroup扩展了View(我认为是正确的)。

其次,不允许将List<ViewGroup>作为List<View>传递。 这是一种编译时保护,可以防止某人将AnotherView添加到此列表中并损害泛型的类型安全性。

List<ViewGroup>不是List<View>的子类型,但是它是List<? extends View>的子类型List<? extends View> List<? extends View> 因此,您可以修改您的方法以接受List<? extends View> 而是改为List<? extends View> ,但要注意,您不能以这种方式添加到传递给该方法的列表中。

与上面提到的上限通配符相反,还有另一种语法称为下限通配符( List<? super ViewGroup> ),它使您可以添加到列表中,但可以通过任何方式传入ViewGroup或其父级列表。

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

暂无
暂无

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

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