有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

两个类之间的递归java泛型

这是一个类似于Possibly recursive Java generics between two classes中提出的问题。然而,正如在另一个线程中所述,一切正常。在我的例子中,不幸的是,我需要使用递归方法的附加类

更具体地说:我想使用边和节点定义一个graph类。然后,我想从graph类中导出一个街道图,它使用道路和交叉点作为边和节点。此外,我还想使用铁路和车站作为边和节点来推导公共交通图。最后,我想定义一个包含街道图或公共交通图的变量。这最后一步是我迄今为止无法实现的。语言太多了;现在让我们看看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;
...

但是,我希望避免对原始类型等发出警告,因此显而易见的方法是:

Graph<Node, Edge> g = street;

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

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

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

谢谢你的帮助

谢谢, 马蒂亚斯


共 (2) 个答案

  1. # 1 楼答案

    正如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 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但不包含在Node和/或Edge接口中的方法,那么您将使用更具体的StreetGraph而不是Graph<?, ?>

    StreetGraph sg = new StreetGraph();
    JunctionNode jn = sg.getNode();
    RoadEdge re = sg.getEdge();
    
  2. # 2 楼答案

    PTGraphStreetGraph的共同超类型是

    Graph<?, ?>
    

    这对你有用吗