Java继承结构问题

Til*_*ill 2 java polymorphism inheritance

我刚刚实现了一些类:

public abstract class Job<T extends ViewerUnion>{
[...]
}

public abstract class ReturnValueJob<T, S extends ViewerUnion> extends Job<S> {
[...]
}

public class MyReturnJob extends ReturnValueJob<Foo, Baa> {
[...]
}

public class JobExecuter {
public static void execute(List<Job> jobList){
for(Job actJob: jobList){
    actJob.startJob();
}
for(Job actJob: jobList){
    actJob.awaitTimeoutOrFinish();
}
}
}
Run Code Online (Sandbox Code Playgroud)

现在我想执行这段代码:

List<Job> list = new LinkedList<MyReturnJob>();
JobExecuter.execute(list);
Run Code Online (Sandbox Code Playgroud)

但是Java在编译时给了我一些错误:

类型不匹配:无法从LinkedList转换为List

我不知道为什么因为MyReturnJob继承了Job.如果我将列表的定义更改为LinkedList<MyReturnJob> list = new LinkedList<MyReturnJob>();

抛出相同的错误 JobExecuter.execute(list);

谢谢你的帮助.

最好的问候,直到

Oli*_*rth 6

这有什么不对?

问题不在于从改变LinkedListList,但在变化包含的类型.Java泛型不是协变的,这意味着你甚至无法做到:

LinkedList<Job> = new LinkedList<MyReturnJob>();
Run Code Online (Sandbox Code Playgroud)

细节...

有关更多信息,请阅读"Java理论与实践:泛型陷阱"一文.这里有相关部分:

事实证明它有一个很好的理由它不起作用(...):它会破坏应该提供的类型安全仿制品.想象一下,你可以指定List<Integer>一个List<Number>.然后,下面的代码将允许您将不属于的内容Integer放入List<Integer>:

List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));
Run Code Online (Sandbox Code Playgroud)

...应用回上下文

文章示例代码可以翻译成这个问题的上下文,如下所示:

List<MyReturnJob> li = new LinkedList<MyReturnJob>();
List<Job> ln = li; // illegal
ln.add(new FooJob());
Run Code Online (Sandbox Code Playgroud)

在哪里FooJob声明为:

public abstract FooJob extends Job<ViewerUnion> {
[...]
}
Run Code Online (Sandbox Code Playgroud)