模式访问者:摘要 class 需要一个函数

Pattern visitor : Abstract class needs a function

我想避免在每个 class 扩展容器中重新定义 accept(),所以我在容器中定义了它。 Java 不会编译它,除非我在访问者中创建一个函数 visit(Container cont)。我以为这样做,我会强制编译但是永远不会使用 visit(Container cont) ...因为 Java 取最低 class,但它没有。

结果:我得到了一个无限递归循环,每次访问(Container cont)...

你能解释一下为什么以及如何修复它吗(没有在每个容器中定义接受并使 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();

}

您必须向访问者添加一个接受类型 Containervisit 方法,因为您在 Container class 中的 accept 方法中传递了静态类型 Containervisit 方法。

这是确保总是有一个 visit 方法匹配调用 visit 方法的容器的动态类型的唯一方法。

假设您的访问者中没有 visit(Container element) 方法,您创建了从 Container 派生的新 class。现在您的代码无法再执行,因为您的 visitor.

中没有匹配的 visit 方法

您可以在访问者中添加抽象方法 visit(Container element) 并删除 visit 方法的其他抽象定义。在您的具体访问者中,您可以实现 visit(Container element) 方法并检查 element 的动态类型。基于这种类型,您可以调用其他方法来完成预期的工作。