gpt4 book ai didi

java - 使用由父类(super class)集合中的子类实现的接口(interface),无需使用instanceof

转载 作者:太空宇宙 更新时间:2023-11-04 09:43:52 25 4
gpt4 key购买 nike

我正在编写一个小型 2D 游戏,所有游戏元素都是 GameObject 的子类。 Game 类具有 GameObject 的集合。我的问题是,当玩家执行操作时,我会遍历 GameObject 集合来查找玩家前面的内容,然后我只想使用 GameObject 子类实现的接口(interface)方法,而不使用 instanceof 和强制转换。

Here is a (very) simplified class-diagram of the situation

我尝试实现访问者模式,但我希望函数 visit()ActivableObstacle 作为参数,而不是 TVWall

这里是一个代码示例:

class Game {
private ArrayList<GameObject> gameObjects;
...
public void actionPerformed(...) {
GameObject current;
//find the focused Game object
...

//What's easiest but I don't want
if(gameObjects instanceOf Obstacle) {
((Obstacle) current).aMethod()
...
} else if (gameObjects instanceOf Activable) {
((Activable) current).activate()
...
}
...

//What visitor allow me
public void watchVisit(TV tv) {
tv.watch();
}
public void hitVisit(Wall w) {
//...
}

//What I want
public void activableVisit(Activable a) {
a.activate();
}
public void walkVisit(Obstacle o) {
//...
}
...
}

游戏对象:

class GameObject {
public void acceptWatch(Game g) {
//Do nothing, only implemented in class TV
}
//Same with wall
...
}

电视:

class TV extends Item implements Activable {
public void acceptWatch(Game g) {
//this works if watchVisit take a "TV" but not if it's a "Activable"
g.watchVisit(this);
}
public void watch() {
...
}
...
}

如何解决这个问题?

最佳答案

不要在 GameObject 中为 watchTV()hitWall() 制作所有这些单独的方法,而是使用一个名为 doButton 的 Abstract 方法制作带有任何公共(public)变量(nameactivatableobstacle 等)的 GameObject Abstract OneActivity().

然后创建其他对象(例如 TVWall),扩展 GameObject 并使用该特定项目在单击时执行的操作覆盖 doButtonOneActivity() 方法。

现在,您的 Game 类只需在 GameObject 上调用 doButtonOneActivity(),该对象本身就会弄清楚它需要做什么,而无需您手动管理。

希望对您有所帮助!

游戏:

public class Game implements Serializable, IClusterable {
private static final long serialVersionUID = 1L;

private ArrayList<GameObject> gameObjects;

public void actionPerformed(GameObject current) {

// Let the object do whatever it's supposed to do on button press, in either case.
current.doButtonOneActivity();

if(current.isActivatable()){
// Do whatever extra thing you need to do if this one is Activatable...
System.out.println("Hey, this thing is activatable!");
} else if (current.isObstacle()){
// Do something an obstacle needs you to do
System.out.println("Hey, this thing is an obstacle!");
}

}
}

GameObject,它是抽象的。

public abstract class GameObject implements Serializable, IClusterable {
private static final long serialVersionUID = 1L;

public String name;
private boolean activatable;
private boolean obstacle;

public GameObject(String name, boolean activatable, boolean obstacle) {
super();
this.name = name;
this.activatable = activatable;
this.obstacle = obstacle;
}

public abstract void doButtonOneActivity();

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public boolean isActivatable() {
return activatable;
}

public void setActivatable(boolean activatable) {
this.activatable = activatable;
}

public boolean isObstacle() {
return obstacle;
}

public void setObstacle(boolean obstacle) {
this.obstacle = obstacle;
}
}

TV,它扩展 GameObject 并填充它需要的方法。

public class TV extends GameObject implements Serializable, IClusterable {
private static final long serialVersionUID = 1L;

public TV(String name, boolean activatable, boolean obstacle) {
super(name, activatable, obstacle);
}

@Override
public void doButtonOneActivity() {
if(isActivatable()){
// do whatever I need to do as a TV when I am activated...
}
if (isObstacle()){
// do whatever I need to do as a TV when I am activated as an obstacle...
}
System.out.println("I'm a TV and I was called. My name is: " + getName());

}
}

The Wall,它扩展了 GameObject 并填充了它需要的方法。

public class Wall extends GameObject implements Serializable, IClusterable {
private static final long serialVersionUID = 1L;

public Wall(String name, boolean activatable, boolean obstacle) {
super(name, activatable, obstacle);
}

@Override
public void doButtonOneActivity() {
if(isActivatable()){
// do whatever I need to do as a Wall when I am activated...
}
if (isObstacle()){
// do whatever I need to do as a Wall when I am activated as an obstacle...
}
System.out.println("I'm a wall and I was called. My name is: " + getName());

}
}

关于java - 使用由父类(super class)集合中的子类实现的接口(interface),无需使用instanceof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55655161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com