在Java中迭代父类的ArrayList时使用Subclass方法

时间:2013-01-20 02:53:05

标签: java methods arraylist instanceof

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

我可以想办法解决这个问题,例如使用单独的ArrayLists。但是,重点是将所有实体保留在全局列表中而不是将它们分开。是否有解决此问题的简单方法,或者我是否需要更改代码的结构?

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

5 个答案:

答案 0 :(得分:5)

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

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

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

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

我不了解您的架构,您可能需要或不需要将rawFPS传递给update()。 (正如@Naveen非常正确地指出的那样,这不是很干净,所以如果可以,请避免它)。另外,如果您的Entity是抽象的,没有自己的功能,请考虑首先将其设为interface

答案 1 :(得分:2)

偶然if(f instanceof Projectile)是真的,你的引用属于Entity类型,它不知道你在子类中声明了什么,因此编译失败

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

使用cast

if(f instanceof Projectile){
  ((Projectile)f).setX(..);
}

答案 2 :(得分:2)

您必须将其强制转换为Projectile才能进行编译。试试这个:

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

这是因为java总是检查声明对象的类型;在您的情况下,这是Entity

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

答案 3 :(得分:0)

Entity应该是interface,并在其上定义了getVelocity()方法。当然,你可以解决问题和演员,但要问问自己,正确的逻辑模型是什么样的。

答案 4 :(得分:0)

说真的,伙计们?糟透了。 Java上的每个指南都告诉你。

这里有一些错误:你正在循环一组实体并使用另一个数据项改变子集的内部状态(子类实例):FPS。如果你在构造弹丸的时候没有FPS,那么这个外类注入它后来似乎是随机的。只需调用FPS上的一组就可以更清晰,然后更新位置。

外类应该只要求弹丸。