我目前正在编写一个游戏,使用基于实体引擎的自写组件的变体。当我定义我的实体和它们所拥有的组件时,我认为应该使用以下思想来适当地压缩它们,以供系统的其他部分使用:
class Entity {
...用于识别不同的组成部分:
enum ComponentID() {
BODY,
GRAPHICS,
INVENTORY;
}
...应持有下列所有组成部分:
EnumMap<ComponentID, ModelComponent> components = new EnumMap<>(ComponentID.class);
}首先,我们有一个名为ModelComponent的超类和一些不同的具体子类,比如Body、Graphics、AI等等,它们扩展了ModelComponent。
组件EnumMap应该保存对实体所拥有的所有ModelComponents的引用。当我想向系统要求一个特定的组件时,问题就出现了。如果我想获得主体组件(例如,因为物理类想要计算一些碰撞),我将编写如下代码:
public Body getBody() {
return (Body) components.get(ComponentID.BODY);
}转换是必要的,因为在我的游戏中的某个地方,如果我想访问实体的速度,我会调用:
Vector2 velocity = entity.getBody().getVelocity();但是,getVelocity()是一个仅在具体子体中定义的方法。
我的问题是:这是对子类降级的正确用法吗?我不知道,是否可以通过更好的设计来避免向下转换,因为很明显,Graphics组件所做的事情与我们所说的Body组件完全不同,所以两者都有完全不同的方法。
编辑:
我忘记提及以下可能对回答这个问题很重要的细节:
1)当然还有更多的实体的具体子类,如玩家、敌人、触发器等,它们都应该有一个不同的组合的ModelComponents。玩家不需要AI组件,就像敌人一样。
( 2)我这次重构的目的是摆脱田园
Body body;
Graphics graphics;
Inventory inventory;
Ai ai;因为在我的游戏中实例化的每个实体都有所有这些字段。enummap可以消除这个问题,因为我将用以下代码行替换所有getXXX()方法:
public ModelComponent get(ComponentID id) {
return components.get(id);
}发布于 2016-08-23 21:14:06
简短的回答是:不。因为你在增加隐式逻辑。在这种情况下,向下转换是可行的,因为您知道它是正确的,因为在代码中,您将设置正确的对象。但是编译器不能检查这一点,其他开发人员也可能无法检查。因此,其他人可以更改代码,编译器不会抱怨,只有在运行时才会引发类强制转换异常。
https://stackoverflow.com/questions/39110383
复制相似问题