Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中通过继承为不同的实现重用算法逻辑_Java_Algorithm_Inheritance_Data Structures - Fatal编程技术网

在java中通过继承为不同的实现重用算法逻辑

在java中通过继承为不同的实现重用算法逻辑,java,algorithm,inheritance,data-structures,Java,Algorithm,Inheritance,Data Structures,我正在尝试用java实现图形数据结构。 以下是课程: interface Graph<N,E> { addNode(N nodeData); createEdge(N src, N dest, E edgeData); //and many more api methods } class GenericGraph<N,E> implements Graph<N,E> { Set<Node<N,E>>

我正在尝试用java实现图形数据结构。 以下是课程:

interface Graph<N,E> {
    addNode(N nodeData);
    createEdge(N src, N dest, E edgeData);
    //and many more api methods
}

class GenericGraph<N,E> implements Graph<N,E> {

    Set<Node<N,E>> vertices;

    static class Node<N,E> {
        private N node;
        private Set<Edge<N, E>> adjacencyList;

        // getters and setters
    }

    static class Edge<N, E> {

        private E edgeData;
        private Node<N, E> src;
        private Node<N, E> dest;

        // getters and setters
    }

    //******** API methods implementation*********

    Node<N, E> findNode(N nodeData) {
        Node<N, E> node = new Node<>(nodeData);
        if (vertices.contains(node)) {
            for (Node<N, E> tempNode : vertices) {
                if (Objects.equals(tempNode, node)) {
                    node = tempNode;
                    return node;
                }
            }
        }
        return null;
    }

    Node<N, E> createNode(N nodeData) {
        Node<N, E> node = findNode(nodeData);
        if (node == null) {
            node = new Node<>(nodeData);
            vertices.add(node);
        }
        return node;
    }

    @Override
    public void addNode(N nodeData) {
        createNode(nodeData);
    }

    // other api methods
}
GenericGraph api方法使用类节点和边来实现

到目前为止,一切都很顺利

现在我想创建一些比GenericGraph有一些额外特性的类,比如BfsGraph、DfsGraph等等

BFS algo需要为其节点提供3个额外参数:

->color 
->parent
->distance
我在想这样创建BfsGraph:

class BfsGraph<N,E> extends GenericGraph<N,E> {

    //access public,protected and default methods of GenericGraph

    private enum NodeColor {
        WHITE, GRAY, BLACK;
    }

    static class BfsNode<N,E> extends GenericGraph.Node<N,E> {
        private NodeColor color = NodeColor.WHITE;
        private Integer distance = Integer.MAX_VALUE;
        private Node<N, E> parent;

        BfsNode(N node) {
            super(node);
        }
    }
}
BfsGraph类扩展了GenericGraph{
//访问GenericGraph的公共、受保护和默认方法
私有枚举节点颜色{
白色、灰色、黑色;
}
静态类BfsNode扩展了GenericGraph.Node{
私有NodeColor color=NodeColor.WHITE;
私有整数距离=Integer.MAX_值;
私有节点父节点;
BfsNode(N节点){
超级节点;
}
}
}
这个设计的问题是,我必须从GenericGraph复制每个方法,并根据自己的需要在BfsGraph中重新实现(节点将更改为BfsNode)

在将来,如果我想做一些其他的实现,那么我再次需要复制和修改所有的方法

必须重用在GenericGraph中编写的算法/逻辑,而不是重写


请建议我一个新的解决方案或任何修改。

根据您的描述,听起来子类需要能够控制两件事:

  • 创建的
    节点
    实例必须是
    节点
    的子类型的实例。
    • 这可以通过在
      GenericGraph
      中创建一个名为
      createNode
      protected
      方法来处理,该方法仅实例化
      节点
      GenericGraph
      可以在需要
      节点
      实例时调用该方法;子类可以重写该方法以提供正确的
      节点子类型
    • 我注意到您已经有了一个
      createNode
      方法,但是除了创建节点之外,它还有其他逻辑。您应该将该方法重命名为能够捕获其全部用途的方法
  • findNode
    方法需要声明为返回
    节点的相应子类型

    • 这可以通过使用子类override
      findNode
      来处理,但是使用override只需将其委托给超类并执行适当的强制转换,如下所示:

      BsfNode<N, E> findNode(N nodeData) {
          return (BsfNode<N, E>) super.findNode(nodeData);
      }
      
      BsfNode findNode(N nodeData){
      return(BsfNode)super.findNode(nodeData);
      }
      
    • 如果您有一组这样的方法,那么您可以考虑让
      GenericGraph
      实际将其节点类型作为类型参数,这样就可以通过泛型的魔力来处理,而不需要显式重写。但听起来你还没有达到那种方法值得采用的程度

(虽然
BfsGraph
听起来不正确,但请提供一个重写算法的示例,而不是从(
Generic
Graph
重复使用它(并且不做完全相同的事情)。(您知道您可以使用
super
限定成员访问/调用)我曾考虑在我需要的某些场景中使用继承,但这种设计看起来不正确。但您的解决方案帮助我将此设计扩展到了某种程度。所以创建BfsGraph是完全错误的解决方案。但无论如何,谢谢。
BsfNode<N, E> findNode(N nodeData) {
    return (BsfNode<N, E>) super.findNode(nodeData);
}