Java泛型类Graph调用T类型的visit()方法提示未定义,原因是什么?
问题原因
你遇到的编译错误根源是泛型无边界约束:Java泛型类定义时,如果没有给泛型参数指定上界,编译器会默认将泛型类型T当做Object类处理,Object类本身没有定义visit()方法、n属性、visited属性,所以在编译Graph类的bfs方法时就会报错,和你后续实例化时传入什么具体类型无关。
修复步骤
- 第一步:抽象节点行为接口
先定义公共接口约束节点必须实现的方法,避免直接访问类属性破坏封装:
public interface VisitableNode { // 标记节点已访问 void visit(); // 获取节点访问状态 boolean isVisited(); // 获取节点数值 int getN(); }
- 第二步:修改自定义Node类实现接口
将Node的属性改为私有,实现接口定义的所有方法:
static class Node implements VisitableNode { private int n; private boolean visited; public Node(int n){ this.n = n; visited = false; } @Override public void visit(){ visited = true; } public void unvisit(){ visited = false; } @Override public boolean isVisited() { return visited; } @Override public int getN() { return n; } }
- 第三步:给Graph泛型加上界约束
修改类定义,告诉编译器所有传入的泛型参数T都必须实现VisitableNode接口,必然包含接口定义的所有方法:
// 修改前:public class Graph<T> public class Graph<T extends VisitableNode>
- 第四步:修正bfs方法中的属性访问
将直接访问属性的逻辑改为调用接口方法:
public void bfs(T node){ Queue<T> q = new LinkedList<>(); node.visit(); System.out.println(node.getN()); q.add(node); while(!q.isEmpty()){ T n = q.remove(); // 注意:原逻辑出队时重复调用了visit和打印,会输出重复节点,可按需调整到未访问判断分支内 n.visit(); System.out.println(n.getN()); for (T i : map.get(n)){ if (!i.isVisited()){ q.add(i); } } } }
内容的提问来源于stack exchange,提问作者brainoverflow
相关产品推荐
相关产品推荐

