java - 访客模式 : overriding vs overloading

标签 java overloading overriding visitor-pattern

要在 Java 中实现访问者模式,您可以使用覆盖或重载。选择取决于还是总是选择两者之一?因为我看不出有什么缺点。因为我认为第一个和第三个示例总能完成工作?

覆盖的访问者

public interface Visitor {
   public void visitX(X x);
   public void visitY(Y y);
}
public class ConcreteVisitor {
   public void visitX(X x) { ... }
   public void visitY(Y y) { ... }
}

public abstract class XY {
   public abstract void accept(Visitor v);
}
public class X extends XY {
   // alternative: one implementation with reflection possible in super class
   public void accept(Visitor v) {
       v.visitX(this);
   }
}
public class Y extends XY {
   // alternative: one implementation with reflection possible in super class
   public void accept(Visitor v) {
       v.visitY(this);
   }
}

重载的访问者

public interface Visitor {
   public void visit(XY xy); // dummy (couldn't otherwise been used in XY class)
   public void visit(X x);
   public void visit(Y y);
}
public class ConcreteVisitor {
   public void visit(XY xy) { ... }
   public void visit(X x) { ... }
   public void visit(Y y) { ... }
}

public abstract class XY {
   public void accept(Visitor v) {
      v.visit(this); // Which is the compile-time/static type of this? XY?
   }
}
public class X extends XY {

}
public class Y extends XY {

}

更好的访问者重载

public interface Visitor {
   public void visit(X x);
   public void visit(Y y);
}
public class ConcreteVisitor {
   public void visit(X x) { ... }
   public void visit(Y y) { ... }
}

public abstract class XY {
   public abstract void accept(Visitor v);
}
public class X extends XY {
   public void accept(Visitor v) {
      v.visit(this);
   }
}
public class Y extends XY {
  public void accept(Visitor v) {
      v.visit(this);
  }
}

最佳答案

Visitor 模式本质上是关于在单分派(dispatch)语言中涵盖双重分派(dispatch)的重要用例。它利用两步习惯用法中的单一调度机制。因此,如果您对这两个步骤之一使用反射,您将不再实现访问者。

是否使用重载 的问题是次要问题,因为它归结为所有visit 方法的名称选择。您可以使用其中任何一种,但重载在专业代码中更有意义。在研究该模式时,单独的名称将更容易理解访问者模式,该模式因其复杂性而臭名昭著。

关于java - 访客模式 : overriding vs overloading,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20730680/

相关文章:

关于模板化类型和类层次结构的 C++ 函数重载解析

scala - 如何访问 Scala 中的 "overridden"内部类?

java - 覆盖继承的变量名

python - sqlalchemy - 反射(reflect)带空格的表和列

java - 如果我们记录一个对象的不可变性,我们能否将其视为不可变的?

java - 在 Play 2.0 中处理 webdav 请求和响应

java - FreeMarker 和 JSP 2 标记文件

java - 如何进行基于注解的RequestMapping

c# - 在 C# 中使用 'this()' 调用重载方法的正确语法是什么?

emacs - Emacs/Elisp 中的多态回调