在java中通过继承为不同的实现重用算法逻辑
我正在尝试用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>>
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
来处理,但是使用override只需将其委托给超类并执行适当的强制转换,如下所示:findNode
BsfNode<N, E> findNode(N nodeData) { return (BsfNode<N, E>) super.findNode(nodeData); }
BsfNode findNode(N nodeData){ return(BsfNode)super.findNode(nodeData); }
- 如果您有一组这样的方法,那么您可以考虑让
实际将其节点类型作为类型参数,这样就可以通过泛型的魔力来处理,而不需要显式重写。但听起来你还没有达到那种方法值得采用的程度GenericGraph
- 这可以通过使用子类override
BfsGraph
听起来不正确,但请提供一个重写算法的示例,而不是从(Generic
)Graph
重复使用它(并且不做完全相同的事情)。(您知道您可以使用super
限定成员访问/调用)我曾考虑在我需要的某些场景中使用继承,但这种设计看起来不正确。但您的解决方案帮助我将此设计扩展到了某种程度。所以创建BfsGraph是完全错误的解决方案。但无论如何,谢谢。
BsfNode<N, E> findNode(N nodeData) {
return (BsfNode<N, E>) super.findNode(nodeData);
}