在java中将不同的子类存储为父类是否不好
将对象存储为其父类并将object.getClass()与要强制转换到子类的预期类进行比较是否被认为是错误的做法 说明:作为2D游戏的一部分,我有几种类型的“游戏对象”对象,如“门户”、“玩家”、“NPC”、“胸部”等。每种对象都存储在一个二维数组中,组成每个关卡,该数组还充当更新和渲染队列,游戏对象包含关卡所需的信息。 如果我将所有对象存储为父类型GameObject,然后将它们强制转换为它们的实际类,例如(在玩家类中): 这通常会更难阅读吗?这样做可能会有什么问题?如果每个对象都使用阵列进行交互,并且我将来可能会有其他类型的“游戏对象”,每个都具有根本不同的功能,那么什么是更好的方法呢 对不起,如果这是罗嗦,因为我真的不知道如何解释这个问题 编辑:我应该澄清类似的代码可能会从GameObject的其他子类运行,而不仅仅是玩家(即NPC或更高的类),重点是能够更改每个子类之间的交互,而无需在每次创建/更改其潜在存储类类型时更改存储级别类。感谢那些推荐在java中将不同的子类存储为父类是否不好,java,casting,Java,Casting,将对象存储为其父类并将object.getClass()与要强制转换到子类的预期类进行比较是否被认为是错误的做法 说明:作为2D游戏的一部分,我有几种类型的“游戏对象”对象,如“门户”、“玩家”、“NPC”、“胸部”等。每种对象都存储在一个二维数组中,组成每个关卡,该数组还充当更新和渲染队列,游戏对象包含关卡所需的信息。 如果我将所有对象存储为父类型GameObject,然后将它们强制转换为它们的实际类,例如(在玩家类中): 这通常会更难阅读吗?这样做可能会有什么问题?如果每个对象都使用阵列进行
instanceof
的人,我已经更新了这个问题,将重点放在其他部分,但从现在起我可能会使用它。谢谢你的反馈
结论:我决定使用daniu答案的一个变体,其中每个游戏对象都有自己的AI子类,它扩展了上述接口的存根/适配器。因此,我不必为任何类实现反应,我可以为同一对象类型提供不同的行为,处理交互应如下所示:
getObject(x,y).getAI().react(obj);
我建议使用
instanceof
而不是比较类本身
private void checkPosition(x, y) {
GameObject obj = Level.getObject(x,y);
if(obj instanceof NPC) {
NPC npc = (NPC)obj;
//interact with npc
} else if(obj instanceof Chest) {
//handle chest
}
}
instanceof
是一个操作符,用于测试对象是否为指定类型,即类
、子类
或接口
阅读教程以获得额外帮助
在强制转换未知对象之前,应始终使用instanceof check。这样做有助于避免运行时发生ClassCastException
而不是
if(obj.getClass() == NPC.class)
最好使用
if (obj instanceof NPC)
除非您想在不允许子类的情况下测试确切的类
另一种选择是让对象自己检查它们的位置,然后就这样做
private void checkPosition(int x, int y) {
GameObject obj = Level.getObject(x,y);
obj.checkPosition()
}
或
取决于此职位检查所需的内容。这是访问者模式的一个用例
添加一个接口(用于可能在关卡中移动的所有内容)
和您的游戏对象
interface GameObject { // or abstract class
// added method
void accept(LevelCrawler lc); // abstract if class
}
LevelCrawler
将由Player
类(或您在编辑中描述的NPC
等)实现
包含if(){…}
块中的代码
那么,你有
class Chest implements GameObject { // I think it's a class, so probably "extends"
void accept(LevelCrawler p) { p.handle(this); } // to call Player#handle(Chest)
}
你的代码看起来像
GameObject o = Level.getObject(x, y);
o.accept(player); // or NPC or whatever is moving right now
看
这样做的好处是,当您创建一个新的GameObject
类时,您可以轻松地将新行为添加到现有的LevelCrawler
类中,并保持checkPosition
代码不变
玩家和NPC都在地下城中移动。游戏中所有对象都有一个超类是正确的。我将使用instanceof
而不是比较getClass
返回值,但是您可以做的事情不多。另外,我会将评估包装在一个策略模式中。我编辑了我的答案,以提供几种类型的移动对象。
interface GameObject { // or abstract class
// added method
void accept(LevelCrawler lc); // abstract if class
}
class Player implements LevelCrawler {
public void accept(Chest chest) { ... }
public void accept(NPC npc) { ... }
}
class Chest implements GameObject { // I think it's a class, so probably "extends"
void accept(LevelCrawler p) { p.handle(this); } // to call Player#handle(Chest)
}
GameObject o = Level.getObject(x, y);
o.accept(player); // or NPC or whatever is moving right now