2

在这个循环中,我将遍历一个 ArrayList 类型Entity,其中包含 Entity 类型的对象以及 Projectile 类型的对象,后者扩展了 Entity。如果对象是 Projectile 的实例,我希望执行以下代码。但是,该getVelocity()方法仅在子类 Projectile 中,而不在 Entity 中。所以我无法编译下面的代码。

我可以想办法解决这个问题,例如使用单独的 ArrayList。但是,关键是将所有实体保留在一个全局列表中,而不是将它们分开。这个问题有一个简单的解决方案,还是我需要改变我的代码结构?

for (Entity f: glo.getList()) {
           if (f instanceof Projectile)
              f.setX(f.getVelocity()/rawFPS);
        }
4

5 回答 5

5

这似乎是一个循环,在游戏引擎的每一次滴答声中都会以某种方式更新您的实体。

在我看来,更清洁的解决方案是:

class Entity {
  ...
  public void update() {}
  ...
}

class Projectile extends Entity {
  ...
  @Override
  public void update() {
    setX(velocity/rawFPS);
  }
  ...
}

我不知道你的架构,你可能需要也可能不需要传递rawFPSupdate(). (正如@Naveen 非常正确地指出的那样,这不是很干净,所以如果可以的话,请避免使用它)。此外,如果您Entity是抽象的,本身没有任何功能,请考虑interface首先将其设为一个。

于 2013-01-20T03:01:43.050 回答
2

甚至if(f instanceof Projectile)是真的,您的引用是Entity不知道您在子类中声明的类型,因此编译失败

Entity在类中提供具有相同签名的空白方法,而不是override在子类中提供并删除instanceof检查,如果它适合您的类模型

或者

使用铸造

if(f instanceof Projectile){
  ((Projectile)f).setX(..);
}
于 2013-01-20T02:55:06.603 回答
2

您必须将其转换为 aProjectile才能编译。尝试这个:

for (Entity f: glo.getList()) {
           if (f instanceof Projectile)
              f.setX(((Projectile)f).getVelocity()/rawFPS);
        }

发生这种情况是因为 java 总是检查对象声明为的类型;在你的情况下,这是Entity.

您可能想要添加一个@SuppressWarnings("unchecked"),以便您的 IDE 和阅读您的代码的任何人都知道未经检查的强制转换是故意的。

于 2013-01-20T02:55:15.603 回答
0

Entity应该真的是一个interface, 上面定义了一个getVelocity()方法。当然,您可以解决问题并进行投射,但问问自己,对于您正在构建的东西,正确的逻辑模型是什么。

于 2013-01-20T02:58:05.410 回答
0

认真的,伙计们?很烂的例子。每个 Java 指南都会告诉你这一点。

这里有一些问题:您正在循环一组实体并使用另一个数据项改变子集(子类实例)的内部状态:FPS。如果您在构建 Projectile 时没有 FPS,那么稍后让这个外部类注入它似乎有点随机。只在 FPS 上调用一个集合并随后更新位置可能会更干净。

外部类可能只需要 Projectiles。

于 2013-01-20T03:01:30.263 回答