2011-07-11 69 views
2

这是一个类似于Possibly recursive Java generics between two classes中提出的问题。但是,至于在其他线程中声明的,一切正常。在我的情况下,我需要使用递归方法的其他类。两类之间的递归java泛型

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

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

现在,到目前为止的辩论。我想要做的是一样的东西:

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

我想要的,但是,为了避免对原材料类型等的警告所以显而易见的方法是:

​​

这一点,但是,不可能的,因为Edge不是Node的ET的有效替代品(这对我来说是绝对清楚的)。我需要这样的东西:

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

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

任何帮助表示赞赏。

感谢, 马蒂亚斯

回答

1

由于保罗已经表明,我认为通配符参数可能是你正在寻找的。

假设你Graph接口有这些方法

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

和你StreetGraph实现他们这样

public class StreetGraph implements Graph<JunctionNode, RoadEdge> { 

    public RoadEdge getEdge() 
    { 
     return edge; 
    } 

    public JunctionNode getNode() 
    { 
     return node; 
    } 

} 

然后,你可以做以下就好了,所有的类型安全和编译器的友好:

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

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

然后工作在NodeEdge接口,与底层实现无关。

如果您需要额外的类型信息,例如如果你想,尤其适用于JunctionNode和RoadEdge,但不包含在节点和/或边缘接口的访问方法,那么你会在更为具体的StreetGraph,而不是一个Graph<?, ?>工作:

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

这个答案是罚款(到问题)。我发布了另一个相当相关的问题[这里](http://stackoverflow.com/questions/6679322/a-more-extensive-recursion-generics-question)。 – Matthias

+0

@Matthias:感谢您的链接,我会研究它。 – emboss

0

两个PTGraphStreetGraph的共同父将

Graph<?, ?> 

这是否对你的工作?