更广泛的递归/泛型问题

时间:2011-07-13 13:02:30

标签: java generics

基于提出的问题并回答here,我有一个更复杂的问题(至少在我看来)。为了使阅读(和回答)更容易,我将在此重述完整的代码示例:

让我们从定义一组类/接口开始:

public interface Node<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> {
  /* internal datastructures here */
}

public interface Edge<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> {
  /* internal datastructures here */
}

public interface Graph<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> {
  /* internal datastructures here */
}

public class JunctionNode implements Node<JunctionNode, RoadEdge> {
}

public class RoadEdge implements Edge<JunctionNode, RoadEdge> {
}

public class StreetGraph implements Graph<JunctionNode, RoadEdge> {
}

public class PTNode implements Node<PTNode, PTEdge> {
}

public class PTEdge implements Edge<PTNode, PTEdge> {
}

public class PTGraph implements Graph<PTNode, PTEdge> {
}

我现在需要定义一个多式联运图,即包含PTEdges和RoadEdges的图表。在我看来,我会通过陈述

来做到这一点
public class IntermodalGraph implements Graph<Node, Edge> {
}

这里编译器对Node和Edge抱怨,因为Node被定义为有两个类型参数,其中一个是从第二个类型(这里是Edge)派生的。这意味着,我必须陈述

public class IntermodalGraph implements Graph<Node<Node, Edge>, Edge> {
}

到目前为止,第一个类型参数(Node)没问题,但第二个参数(Edge)失败,因为edge再次获取两个类型参数,第一个从Node派生。所以,我会写

public class IntermodalGraph implements Graph<Node<Node, Edge>, Edge<Node<Node, Edge>>, Edge> {
}

现在,第二个类型参数没问题,但第一个参数(显然)再次“坏”。

最后,我想实现一些像

这样的代码
IntermodalGraph ig = new IntermodalGraph();
ig.add(new PTEdge());
ig.add(new RoadEdge());

Set<Edge> edges = ig.getEdges();

那么有人知道如何在保持类型安全的同时实现这一目标吗?

LG, 的Matthias

2 个答案:

答案 0 :(得分:2)

由于您的课程已经指定了泛型,因此您可以将IntermodalGraph课程声明为

public class IntermodalGraph<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> implements Graph<NT, ET> {
}

这不应该发出任何警告。

** 编辑 **

你无法实现你想要的,即

IntermodalGraph ig = new IntermodalGraph();
ig.add(new PTEdge());
ig.add(new RoadEdge());

Set<Edge> edges = ig.getEdges();
除非添加unchecked注释,否则

不会抛出任何@SuppressWarnings("unchecked")警告。但是,仍然是有效的Java语法并且可以工作;通用NT默认为NodeETEdge

答案 1 :(得分:0)

正如toto已经指出的那样,你定义了一个类型可检查合同,然后继续打破它 - 并且编译器介入。类型安全的解决方案是简单地将合同分为两个,一个较弱且一个更严格的:一个Graph<N extends Node<?, ?>, E extends Edge<?, ?>>接口以及StrictGraph<N extends Node<N, E>, E extends Edge<N, E>>扩展Graph<N, E>的接口。