问题描述
我正在使用访问者模式来遍历异构对象结构,并希望在我的通用接口中重载visit()
方法以不同方式处理不同的子类型。
为什么在下面的代码中没有调用visit(Bar)
,我能做些什么来修复它?
在此先感谢您的帮助!
史蒂夫
package test;
import java.util.ArrayList;
public class OverloadTest {
public static void main(String[] args) {
// Create a visitable collection
FooCollection c = new FooCollection();
// Add some members
c.add(new Foo());
c.add(new Bar());
// Visit
c.accept(new IVisitor<Foo>() {
public void visit(Foo foo) {
System.out.println("Foo");
}
public void visit(Bar bar) {
System.out.println("Bar");
}
});
}
public static class Foo {
}
public static class Bar extends Foo {
}
public static interface IVisitor<T> {
public void visit(T object);
}
public static class FooCollection {
private final ArrayList<Foo> m_list = new ArrayList<>();
public void accept(IVisitor<Foo> visitor) {
for (Foo foo : m_list) {
visitor.visit(foo);
}
}
public void add(Foo foo) {
m_list.add(foo);
}
}
}
1楼
您在public void accept(IVisitor<Foo> visitor)
实现了IVisitor<Foo>
所以,唯一可见的方法是public void visit(Foo foo)
。
解决此问题的一种选择是保留 IVisitor 通用(从接口声明中删除<Foo>
)。
它的方法变成:
public void visit(Object object);
另一种选择是将方法接受更改为:
public void accept(IVisitor<Object> visitor) {
...
}
2楼
如果我修改 IVisitor 以包含每个所需类型的方法,它会起作用:
public static interface IFooVisitor {
public void visit(Foo foo);
public void visit(Bar bar);
}
并为每个实现一个 accept() 方法:
public static class Foo {
public void accept(IFooVisitor visitor) {
visitor.visit(this);
}
}
public static class Bar extends Foo {
public void accept(IFooVisitor visitor) {
visitor.visit(this);
}
}
我失去了一些灵活性,并将 Foo 和 Bar 耦合到访问者模式,但它有效。