如何实现抽象类或接口的子类型的访问者模式?

问题描述 投票:0回答:2

我有这个具体问题,我无法解决其他问题。我正在尝试为游戏实现访问者,访问者是Attack类,它必须在矩阵中搜索可能包含Characters的单元格,然后如果角色是敌人而不是朋友,则会损坏它。

我遇到麻烦的是没有使用InstanceOf来访问角色,因为它违反了开放封闭原则。这是我的代码:

访客界面

public interface Visitor {
    public void visit(GroundCell c);
    public void visit(MountainCell c);
    public void visit(BuildingCell c);
    public void visit(WaterCell c);
    public void visit(Foe f);
    public void visit(Friend f);}

攻击抽象类

public abstract class Attack implements Visitor {

}

攻击具体课程

public class TankAttack extends Attack{

...

@Override
public void visit(GroundCell c) {
    //here, i'd like to call  c.getCharacter.accept(this) 
}

但是我得到一个错误,说我应该首先实现Visit(字符c),当我只需要它的子类时。

我应该在TankAttack类中访问Character的Friend或Foe子类,而不是使用InstanceOf来破坏设计?

编辑澄清:朋友和敌人是角色的子类。

java oop design-patterns solid-principles visitor
2个回答
0
投票

访客不以这种方式工作。

此处声明为参数的所有类都是访问类:

public void visit(GroundCell c);
public void visit(MountainCell c);
public void visit(BuildingCell c);
public void visit(WaterCell c);
public void visit(Foe f);
public void visit(Friend f);}

所有这些都必须定义一个accept(Visitor visitor)方法,意思是“我接受访问者访问”。 在它们内部,我们调用:visitor.visit(this)以预期的超载(双重调度)有效地执行访问。

这样你就可以写:

Attack attack = new TankAttack(); // visitor
Visited visitedOne = new GroundCell(); // visited one
Visited visitedTwo = new MountainCell(); // visited two

// accept the visitor and perform the double dispatch to invoke the specific method
visitedOne.accept(attack); 
visitedTwo.accept(attack); 

或者更一般地,您将一个基本类型为visitor的方法公开为参数,例如:

public void attack(Visited visited, Attack attack){
     visited.accept(attack); // no need instance of
}

并使用它:

attack(new GroundCell(), attack); 
attack(new MoutainCell(), attack); 

0
投票

几小时后我解决了。这个问题不是由于访问者模式的错误实现引起的,而是因为超类被称为Character,就像java.lang.Character一样。在编写java游戏时要小心不要覆盖这个类。

© www.soinside.com 2019 - 2024. All rights reserved.