如何从父泛型类型引用子泛型类型?

时间:2015-03-05 00:13:24

标签: java generics inheritance

这是方案

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();

为什么?

有没有办法通过父类型引用?

4 个答案:

答案 0 :(得分:3)

This is how generics works。您已明确声明类ChildParent<MyClass2>的子类。但Parent<MyClass2>不是Parent<MyClass1>的子类,因此Child不是Parent<MyClass1>的子类。

将构造函数调用更改为

Parent<? extends MyClass1> p = new Child();

答案 1 :(得分:2)

这一行

Parent<MyClass1> p = new Child();

没有编译,因为Child类已将类型参数T定义为MyClass2。即使ChildParent<MyClass2>,所有Parent<MyClass2>个对象都是Parent<MyClass1>个对象,MyClass2不是MyClass1。这是因为Java的泛型是不变的。

使用MyClass1时进行编译的解决方案是使用有界通配符。

Parent<? extends MyClass1> p = new Child();

通配符允许MyClass2MyClass1之间的关系扩展为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();

所以现在你告诉编译器TMyClass1的子类,所以编译器就可以了。

答案 3 :(得分:0)

根据您的Child班级定义,您声明唯一类型的通用Parent会接受MyClass2。如果您希望<{> 1}}中 <{strong> MyClass1MyClass2被接受为Generics,请执行以下操作:

Parent