我有这个具体问题,我无法解决其他问题。我正在尝试为游戏实现访问者,访问者是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来破坏设计?
编辑澄清:朋友和敌人是角色的子类。
访客不以这种方式工作。
此处声明为参数的所有类都是访问类:
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);
几小时后我解决了。这个问题不是由于访问者模式的错误实现引起的,而是因为超类被称为Character
,就像java.lang.Character
一样。在编写java游戏时要小心不要覆盖这个类。