本文介绍了一个更广泛的递归/泛型问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据提问并回答了的问题,我有第二个问题,更复杂的一个(至少在我看来)。为了使阅读(和回答)变得更容易,我将在这里重申完整的代码示例:



让我们从定义一组类/接口开始: p扩展Edge< NT,ET>> ;. {
/ *这里的内部数据结构* /
}

公共接口边缘< NT扩展节点< NT,ET>,ET扩展Edge< NT,ET>> {
/ *这里的内部数据结构* /
}

public interface Graph< NT extends Node< NT,ET>,ET extends Edge< NT,ET>> {
/ *这里的内部数据结构* /
}

public class JunctionNode实现Node< JunctionNode,RoadEdge> {
}

public class RoadEdge实现Edge< JunctionNode,RoadEdge> {
}

公共类StreetGraph实现Graph< JunctionNode,RoadEdge> {
}

公共类PTNode实现Node< PTNode,PTEdge> {
}

公共类PTEdge实现Edge< PTNode,PTEdge> {
}

公共类PTGraph实现Graph< PTNode,PTEdge> {
}

现在我需要定义一个多式联运图,即一个包含PTEdges的图和RoadEdges一样。在我看来,我会这样做:

$ public $ IntermodalGraph实现Graph< Node,Edge> {
}

这里是编译器对Node和Edge的抱怨,因为Node被定义为拥有两个类型参数,其中一个来自第二类型(这里是Edge)。这意味着,我将不得不声明

  public class IntermodalGraph实现Graph< Node< Node,Edge>,Edge> {
}

到目前为止,第一个类型参数(Node)没问题,但第二个(边缘)失败,因为边缘再次获得两个类型参数,第一个从节点派生。因此,我会写出:

  public class IntermodalGraph实现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

解决方案

由于您的类已经指定了泛型,可以将 IntermodalGraph 类声明为

  public class IntermodalGraph } 

这不应该引发任何警告。



** 编辑 **



您无法完成您想要的功能,即

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

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

不会抛出任何未经检查的警告,除非您添加 @SuppressWarnings(unchecked)注释。但是,它仍然是有效的Java语法并且可以工作;通用 NT 将默认为 Node ET 边缘


Based on the question asked and answered here, I have a second, more complex one (at least in my opinion). To make reading (and answering) easier, I will, however, restate the complete code example here:

Let us begin by defining a set of classes/interfaces:

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> {
}

I now need to define an intermodal graph, i.e. a graph containing PTEdges as well as RoadEdges. In my opinion, I would do this by stating

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

Here the compiler complaints on Node and Edge, since Node is defined to have two type parameters whereupon one is derived from the second type (here Edge). This means, I would have to state

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

So far, the first type parameter (Node) is ok, but the second one (Edge) fails since edges takes two type parameters again, the first one derived from Node. So, I would write

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

Now, the second type parameter is ok, but the first one is (obviously) "bad" again.

In the end, I would like to achieve some code like

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

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

So does anybody have an idea how to achieve this while keeping type safe?

lg,Matthias

解决方案

Since your classes already specify the generics, you could declare your IntermodalGraph class as

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

And this should not throw any warnings.

** EDIT **

You can't accomplish what you want, that is having

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

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

not throw any unchecked warnings, unless you add @SuppressWarnings("unchecked") annotations. But, it is still valid Java syntax and will work; the generic NT will default to Node and ET to Edge

这篇关于一个更广泛的递归/泛型问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 23:38