这是方案
class MyClass1{
}
class MyClass2 extends MyClass1{
}
class Parent<T>{
List<T> list;
}
class Child extends Parent<MyClass2>{
}
这不会编译
Parent<MyClass1> p = new Child();
这样做
Parent<MyClass2> p = new Child();
为什么?
有没有办法通过父类型引用?
答案 0 :(得分:3)
This is how generics works。您已明确声明类Child
是Parent<MyClass2>
的子类。但Parent<MyClass2>
不是Parent<MyClass1>
的子类,因此Child不是Parent<MyClass1>
的子类。
将构造函数调用更改为
Parent<? extends MyClass1> p = new Child();
答案 1 :(得分:2)
这一行
Parent<MyClass1> p = new Child();
没有编译,因为Child
类已将类型参数T
定义为MyClass2
。即使Child
是Parent<MyClass2>
,所有Parent<MyClass2>
个对象都是Parent<MyClass1>
个对象,MyClass2
不是MyClass1
。这是因为Java的泛型是不变的。
使用MyClass1
时进行编译的解决方案是使用有界通配符。
Parent<? extends MyClass1> p = new Child();
通配符允许MyClass2
和MyClass1
之间的关系扩展为Parent<MyClass2>
和Parent<? extends MyClass1>
。
答案 2 :(得分:1)
您所谈论的是一个名为协方差的概念。在您的实现中,MyClass1 extends MyClass2
并不意味着Parent<MyClass1> extends Parent<MyClass2>
所以Parent<MyClass1> p = new Child();
无法编译。
你必须在实例化中明确提到这一点:
Parent<? extends MyClass1> p = new Child();
所以现在你告诉编译器T
是MyClass1
的子类,所以编译器就可以了。
答案 3 :(得分:0)
根据您的Child
班级定义,您声明唯一类型的通用Parent
会接受MyClass2
。如果您希望<{> 1}}中 <{strong> MyClass1
和MyClass2
被接受为Generics,请执行以下操作:
Parent