我想避免在每个扩展Containers的类中重新定义accept(),所以我在容器中定义了它。除非我在访问者中创建函数访问(Container cont),否则Java不会编译它。我认为通过这样做,我会强制编译,但访问(Container cont)永远不会被使用......因为Java采用最低的类,但它没有。
结果:我每次访问时都会遇到无限递归循环(Container cont)...
你能解释一下为什么以及如何修复它(无需在每个容器中定义接受并使 FinderPackBuilder 成为一个接口(interface))。
谢谢!
编辑: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();
}
最佳答案
您必须向您的访问者添加一个接受类型 Container
的 visit
方法,因为在 Container
中的 accept
方法code> 类,您将静态类型 Container
传递给 visit
方法。
这是确保始终存在与调用 visit
方法的容器的动态类型相匹配的 visit
方法的唯一方法。
假设您的访问者中没有 visit(Container element)
方法,并且您创建了从 Container
派生的新类。现在您的代码无法再执行,因为您的 visitor
中没有匹配的 visit
方法。
您可以在访问者中添加一个抽象方法visit(Container element)
,并删除visit
方法的其他抽象定义。在具体访问者中,您可以实现 visit(Container element)
方法并检查 element
的动态类型。基于这种类型,您可以调用其他方法来完成预期的工作。
关于java - 模式访问者 : Abstract class needs a function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31828934/