我想避免在每个扩展容器的类中重新定义accept(),所以我在容器中定义它。除非我在访问者中创建函数访问(Container cont),否则Java不会编译它。我认为通过这样做,我会强制编译,但访问(容器续)将永远不会被使用...因为Java占用最低级别,但它没有。
结果:每次访问时都使用无限递归循环(Container cont)...
你能解释一下为什么以及如何解决它(没有在每个容器中定义accept并使FinderPackBuilder成为一个接口)。
谢谢!
编辑:element.getClass()的结果永远不是一个容器,我测试过它。
public abstract class FinderPackBuilderVisitor {
abstract public Document visit (Module module);
abstract public Document visit (Dashboard dashboard);
abstract public Document visit (Section section);
abstract public Document visit (Metric metric);
// The last visit method is here to ensure that all containers can use visit. It will never be used since Container is not Instantiable.
// Another alternative would be to make this an interface and delete this method but we would have to dupliacte code in every instantiable class.
Document visit (Container element){
System.out.println(element.getClass());
System.out.println("This function shouldn't be taken");
return visit(element);
}
public abstract class Container<T extends Container> {
protected String name;
protected ArrayList<T> children;
public Container(String n, ArrayList<? extends T> c){
name = n;
children = new ArrayList<T>();
for (T child : c){
children.add((T)child.getCopy());
}
}
Document accept(FinderPackBuilderVisitor visitor){
for (T child : children){
child.accept(visitor);
}
System.out.println(this.getClass());
return visitor.visit(this);
}
abstract Container<T> getCopy();
}
答案 0 :(得分:1)
您必须向访问者添加接受visit
类型的Container
方法,因为accept
类中的Container
方法会传递静态类型{{1} } Container
方法。
这是避免唯一的方法,即始终有visit
方法匹配调用visit
方法的容器的动态类型。
想象一下,您的访问者中没有visit
方法,而您创建的新类来自visit(Container element)
。现在,您的代码无法执行,因为Container
中没有匹配的visit
方法。
您可以在命令中添加抽象方法visitor
,并删除visit(Container element)
方法的其他抽象定义。在具体的访问者中,您可以实现visit
方法并检查visit(Container element)
的动态类型。基于此类型,您可以调用其他方法来完成预期的工作。