Java 是否可以使用访问者模式执行一般的双重分派?
如果搜索访问者模式的通用版本,您会发现如下内容:Java 是否可以使用访问者模式执行一般的双重分派?,java,generics,Java,Generics,如果搜索访问者模式的通用版本,您会发现如下内容: public abstract class Element { public void accept(Visitor<? extends Element> v) { v.visit(this); } } public interface Visitor<T extends Element> { void visit(T element); } 公共抽象类元素{ 公共无效接受(访客
public abstract class Element {
public void accept(Visitor<? extends Element> v) {
v.visit(this);
}
}
public interface Visitor<T extends Element> {
void visit(T element);
}
公共抽象类元素{
公共无效接受(访客它不会破坏它,只是让它变得丑陋。而不是:
class MyVisitor implement Visitor<Element>{
void visit(ElementA ea) {..}
void visit(ElementB eB) {..}
}
编辑
您可以有这样一个解决方案:
class ElementVisitor {
void visit(ElementA ea)
void visit(ElementB eb)
}
如果客户现在喜欢:
class ElementA {
void accept(ElementVisitor ev) {
ev.accept(this); // this call will be dispatched to visit(ElementA)
}
}
然后访问被分派到正确的方法。这种方法的问题是它不是通用的,你必须为要访问的每个类型族编写一个不同的Visitor
接口。另一种方法是,你只有一个Visitor
接口来访问所有类型。这就是我的想法。谢谢!但这只是一个遗憾。它有一点很难看,但它很蹩脚,因为它失去了编译安全性:(嗯,你到底是什么意思?如果你检查instanceof
,那么强制转换是安全的。如果你熟悉scala
的模式匹配机制,(这是这个解决方案更好的版本)它还被编译成instanceof
检查和强制转换。我熟悉模式匹配,但不知道它被编译成instanceof检查。酷!不过,我的意思是,通过指定一个重载访问方法的接口,可以获得编译时安全性,该接口必须由访问者实现才能进行编译。我想你可以o与在检查实例中调用的visit*方法相同。是的,我在代码示例中使用visit(ElementA ea)
显示了这种情况。不过,您仍然必须将其强制转换为ElementA
class ElementA {
void accept(ElementVisitor ev) {
ev.accept(this); // this call will be dispatched to visit(ElementA)
}