在Java中遍历父类的ArrayList时使用Subclass方法
Posted
技术标签:
【中文标题】在Java中遍历父类的ArrayList时使用Subclass方法【英文标题】:Using Subclass method when iterating through ArrayList of parent class in Java 【发布时间】:2013-01-03 11:33:49 【问题描述】:在这个循环中,我正在遍历 Entity
类型的 ArrayList,其中包含 Entity 类型的对象以及 Projectile 类型的对象,后者扩展了 Entity。如果对象是 Projectile 的实例,我希望执行以下代码。但是,getVelocity()
方法仅在子类 Projectile 中,而不在 Entity 中。所以我无法编译下面的代码。
我可以想办法解决这个问题,例如使用单独的 ArrayList。但是,关键是将所有实体保留在一个全局列表中,而不是将它们分开。这个问题有简单的解决方案,还是我需要改变我的代码结构?
for (Entity f: glo.getList())
if (f instanceof Projectile)
f.setX(f.getVelocity()/rawFPS);
【问题讨论】:
【参考方案1】:这似乎是一个循环,在游戏引擎的每一次滴答声中都会以某种方式更新您的实体。
在我看来,更清洁的解决方案是:
class Entity
...
public void update()
...
class Projectile extends Entity
...
@Override
public void update()
setX(velocity/rawFPS);
...
我不知道您的架构,您可能需要也可能不需要将rawFPS
传递给update()
。 (正如@Naveen 非常正确地指出的那样,这不是很干净,所以如果可以的话,请避免使用它)。此外,如果您的 Entity
是抽象的,本身没有任何功能,请首先考虑将其设为 interface
。
【讨论】:
+1 这是一个很好的面向对象的方法。让对象在知道如何更新/渲染时自行更新/渲染,必要时可以通过使用内部/非标准 API 受益。 我没有想过拥有独立的更新方法。鉴于我的其余代码,我将研究它是否可行。 嗯...将rawFPS
传递给所有实体闻起来有点奇怪,因为大多数Entity
s 会忽略它。
@Navin 好吧,这取决于。在游戏中,大多数需要更新的实体都会根据经过的时间进行更新,因此实际上大多数实体都需要rawFPS
。但我同意你的看法:如果可以,最好避免这种情况。
传递更新程序并使用特定于类型的回调。这将使它成为非常接近访客模式的双重调度。【参考方案2】:
您必须将其转换为 Projectile
才能编译。试试这个:
for (Entity f: glo.getList())
if (f instanceof Projectile)
f.setX(((Projectile)f).getVelocity()/rawFPS);
这是因为 java 总是检查对象声明的类型;在您的情况下,这是Entity
。
您可能想要添加一个@SuppressWarnings("unchecked")
,以便您的 IDE 和阅读您的代码的任何人都知道未经检查的强制转换是故意的。
【讨论】:
【参考方案3】:即使if(f instanceof Projectile)
是真的,你的引用是Entity
类型的,它不知道你在子类中声明了什么,所以编译失败
在 Entity
类中提供具有相同签名的空白方法,而不是在子类中提供 override
并删除 instanceof
检查,如果它适合您的类模型
或
使用强制转换
if(f instanceof Projectile)
((Projectile)f).setX(..);
【讨论】:
【参考方案4】:Entity
确实应该是一个interface
,并在其上定义了一个getVelocity()
方法。当然,您可以解决问题并进行投射,但请问问自己,对于您正在构建的内容,正确的逻辑模型是什么。
【讨论】:
我不是反对者,但我猜这是因为Entity
可能没有速度,所以给它一个getVelocity()
是没有意义的。【参考方案5】:
说真的,伙计们?很烂的例子。每一个 Java 指南都会告诉你这一点。
这里出了点问题:您正在循环一组实体并使用另一个数据项 FPS 更改子集(子类实例)的内部状态。如果您在构建 Projectile 时没有 FPS,那么稍后让这个外部类注入它似乎有点随机。只在 FPS 上调用一个集合然后更新位置可能会更干净。
外部类可能只需要 Projectiles。
【讨论】:
instance of sucks
真的吗?这个问题正是你使用instance of
的那种情况。
我倾向于同意 Rob 的观点,instanceof 确实很烂。我没有在回答中提到那部分。
嗯...为什么是suck?
因为它不是面向对象的。如果您使用的是实例,则您的模型有缺陷。
第二个链接,老兄:来自 Google 的javapractices.com/topic/TopicAction.do?Id=31。以上是关于在Java中遍历父类的ArrayList时使用Subclass方法的主要内容,如果未能解决你的问题,请参考以下文章