两类之间的递归java泛型 [英] recursive java generics between two classes

查看:93
本文介绍了两类之间的递归java泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题与中提到的问题类似,可能是递归的Java泛型两个班级。但是,至于在其他线程中声明的,一切正常。在我的情况下,我不幸的需要使用递归方法的附加类。

更具体地说:我想定义一个使用边和节点的图类。然后,我想从使用道路和路口作为边缘和节点的图类中派生出街道图。另外,我想使用铁路来推导公共交通图,并停止边和节点。最后,我想定义一个拥有街道图或公共交通图的变量。最后一步是迄今为止我无法实现的目标。用词很多;现在让我们来看看Java代码:

  public interface Node< NT extends Node< NT,ET>,ET extends 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> {b $ b}

到目前为止,我想要做的是这样的:

  StreetGraph street = new StreetGraph(); 
PTGraph ptGraph = new PTGraph();
Graph g = street;
...
g = ptGraph;
...

但是,我想避免原始类型等的警告。因此,显而易见的方式是:

  Graph< Node,Edge> g =街道; 

然而,这是不可能的,因为Edge不是Node的ET的有效替代品对我来说是绝对清楚的)。我需要的东西如下所示:

  Graph ,ET = Edge > G; 

这是(如预期的)无效的Java代码。
任何想法,如何在没有警告/错误和类型安全的情况下实现有效的Java代码?

任何帮助表示赞赏。



感谢,
Matthias

解决方案

正如Paulo已经说过的,我认为通配符参数可能是您

假设你的 Graph 接口有这些方法

  public interface Graph< NT extends Node< NT,ET>,ET extends Edge< NT,ET>> {
public NT getNode();
public ET getEdge();

和您的 StreetGraph 以这种方式实现它们

  public class StreetGraph实现Graph< JunctionNode,RoadEdge> {

public RoadEdge getEdge()
{
return edge;
}

public JunctionNode getNode()
{
return node;
}

}

然后您可以执行以下操作很好,所有类型安全和编译器友好:

 图<?,?> g =新的PTGraph(); 
g = new StreetGraph();

节点<?,?> n = g.getNode();
Edge<?,?> e = g.getEdge();

然后在 Node Edge 接口,不管底层实现如何。

如果您需要额外的类型信息,例如如果您想访问特定于JunctionNode和RoadEdge但未包含在Node和/或Edge接口中的方法,那么您可以使用更具体的 StreetGraph ,而不是图表<?,?>

  StreetGraph sg = new StreetGraph (); 
JunctionNode jn = sg.getNode();
RoadEdge re = sg.getEdge();


This is a question similar to the one asked in Possibly recursive Java generics between two classes. However, so far as stated in that other thread, everything worked alright. In my case, I need unfortunately additional classes using the recursive methods.

To be more specific: I want to define a graph class using edges and nodes. Then, I want to derive a street graph from the graph class which is using roads and junctions as edges and nodes. Additionally, I want to derive a public transport graph using railways and stops as edges and nodes. Finally, I want to define a variable holding either a street graph or a public transport graph. This last step is, what I could not achieve so far. So much with words; now let us have the Java code:

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

Now, so far the defitions. What I want to do is something like:

StreetGraph street = new StreetGraph();
PTGraph ptGraph = new PTGraph();
Graph g = street;
...
g = ptGraph;
...

I want, however, to avoid warnings on raw types, etc. So the obvious way would be:

Graph<Node, Edge> g = street;

This is, however, not possible, since Edge is not a valid substitute for ET of Node (which is absolutely clear for me). I would need something like:

Graph<NT = Node<ET>, ET = Edge<NT>> g;

This is (as expected) not valid Java code. Any ideas, how to achieve valid Java code without warnings/errors and type safety?

Any help appreciated.

Thanks, Matthias

解决方案

As Paulo already stated I think that wildcard parameters may be what you are looking for.

Suppose your Graph interface has these methods

public interface Graph<NT extends Node<NT, ET>, ET extends Edge<NT, ET>> {
  public NT getNode();
  public ET getEdge();
}

and your StreetGraph implements them this way

public class StreetGraph implements Graph<JunctionNode, RoadEdge> {

    public RoadEdge getEdge()
    {
        return edge;
    }

    public JunctionNode getNode()
    {
        return node;
    }

}

Then you can do the following just fine, all type-safe and compiler-friendly:

    Graph<?, ?> g = new PTGraph();
    g = new StreetGraph();

    Node<?, ?> n = g.getNode();
    Edge<?, ?> e = g.getEdge();

and then work on the Node and Edge interfaces, agnostic of the underlying implementation.

If you need the extra type information, e.g. if you wanted to access methods that are particular to JunctionNode and RoadEdge but not contained in the Node and/or Edge interfaces, then you would work on the more specific StreetGraph instead of a Graph<?, ?>:

StreetGraph sg = new StreetGraph();
JunctionNode jn = sg.getNode();
RoadEdge re = sg.getEdge();

这篇关于两类之间的递归java泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆