[英]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
方法。
摘要: View
是ViewGroup
,但是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.