今天我正在用访客模式做一些功课,我做了一个看起来有点像这样的访客(来自wikipedia的编辑样本代码):
class CarElementPrintVisitor implements CarElementVisitor {
public void visit(CarElement element) {
if (element.getClass() == Wheel.class)
{
return visit((Wheel)element);
}
else if (element.getClass() == Engine.class)
{
return visit((Engine)element);
}
else if (element.getClass() == Body.class)
{
return visit((Body)element);
}
else //if (v.getClass() == Car car.class)
{
return visit((Car)element);
}
}
public void visit(Wheel wheel) {
System.out.println("Visiting " + wheel.getName() + " wheel");
}
public void visit(Engine engine) {
System.out.println("Visiting engine");
}
public void visit(Body body) {
System.out.println("Visiting body");
}
public void visit(Car car) {
System.out.println("Visiting car");
}
}
“公共无效访问(CarElement元素)”方法有点难看(如果添加更多CarElements需要维护很长时间)但是我想保留方法,所以我试着做得更好。
我最终尝试了这个:
public void visit(CarElement element) {
return visit(element.getClass().cast(element));
}
但是只返回“visit(CarElement element)”,即使element.getClass()返回正确的类,所以它最终会进入无限循环。
有谁知道怎么做,我想做什么? (如果有可能,我不确定)。
答案 0 :(得分:3)
您错过了访问者模式的优点:必须在CarElement界面中使用accept(CarElementVisitor)
方法,并使用approriate类型调用访问者自身。重新阅读维基百科文章。
答案 1 :(得分:1)
上一版本的问题是您尝试在Java不支持的运行时使用重载。 Java可以根据调用方法的对象类型调用各种实现,而不是调用参数类型。
以下是访客模式的示例,它可以像你(希望)那样工作:
class EventA {
void accept(Visitor visitor) {
visitor.visit(this);
}
}
class EventB {
void accept(Visitor visitor) {
visitor.visit(this);
}
}
interface Visitor {
void visit(EventA e);
void visit(EventB e);
}
class VisitorImpl implements Visitor {
public void visit(EventA e) {
System.out.println("EventA");
}
public void visit(EventB e) {
System.out.println("EventB");
}
}
public class Main {
public static void main(String[] args) {
EventA event = new EventA();
event.accept(new VisitorImpl());
}
}
请注意,每次添加要访问的新类型时,仍需要扩展Visitor界面。 请参阅我的this回答。
希望,这有点帮助)
答案 2 :(得分:0)
您可以在CarElement上使用抽象方法。
public abstract void visit();
class Wheel extends CarElement {
public void visit() {
System.out.println("Visiting " + getName() + " wheel");
}
}
CarElement ce = new Wheel();
ce.visit();