Java - 传递接口类型的ArrayList

时间:2012-05-23 02:07:46

标签: java interface arraylist

我有一个可破坏的接口,如下所示

public interface Damageable {
    public void handleCollision(float impulse);
}

实现此接口的类,BaseObject

public class BaseObject implements Damageable

现在在第三个类中,我有一个BaseObject类型的ArrayList

public class ObjectManager {    
    public ArrayList<BaseObject> bodies;

我要做的是将ArrayList主体传递给另一个接受ArrayList的类的方法

public CollisionManager( ArrayList<Damageable> _bodies) {
        bodies = _bodies;
}

Java不允许我做新的CollisionManager(主体),其中的主体是ArrayList类型,而BaseObject实现了Damageable

我尝试过施法。说不能投 ArrayList<BaseObject>到ArrayList 也尝试使用Class<? extends Damageable>,但后来我无法调用接口Damageable中声明的方法。我怎样才能传递ArrayList?

3 个答案:

答案 0 :(得分:37)

你必须明确你的泛型。因此,您必须告知编译器您的泛型类型 本身不是Damagable,而是扩展 {{1 }}:

Damagable

顺便提一下,请注意我已将变量更改为public CollisionManager(ArrayList<? extends Damagable> bodies) { 而不是bodies。下划线不是标准Java编码约定的一部分。


编辑以回应OP的评论

让我们说,你有一个名为_bodies具体类,而不是一个接口。告诉编译器Damagable说它不必是<? extends Damagable>的实例。它的好的类型扩展 Damagable。否则,编译器会假定您有Damagable 完全

当您将Damagable视为接口时,它没有多大意义,因为在某些情况下您不会拥有Damagable的实例。但它们的工作方式基本相同。

您必须记住,您正在使用Java 类型,而不是类。 Java的类型语法和结构不如它的类结构健壮。在类型方面,没有Damagable的概念。


上一轮编辑

最后,我应该注意,为方法/构造函数参数和方法返回类型使用接口通常会更好。这允许您和那些使用您的方法的人使用您喜欢的任何实现,并允许您随意更改您的实现。

因此,对于这些修订,您将拥有:

implements

答案 1 :(得分:2)

尝试ArrayList<? extends Damageable > _bodies

这表示你想要一个由Class组成的ArrayList,它扩展(实现良好)Damageable

答案 2 :(得分:2)

其他人无疑会从Java语法角度指出技术解决方案。

我要提一些你应该考虑的设计问题:

  • 您的BaseObject实现了Damageable。这意味着所有BaseObject都是可损坏的。那为什么不做一个CollisionManager(ArrayList<BaseObject>)?除非你打算在其他地方使用Damageable(即有些东西是可破坏但不是BaseObjects),否则它似乎是一种不必要的抽象。
  • 通常,对于游戏/模拟中的碰撞检测,您可能希望使用空间数据结构进行碰撞检测(例如Octree,Quadtree或AABB树)而不是ArrayList。在ArrayList中搜索冲突是O(n ^ 2)算法。如果您有很多活动对象,这将成为一个大问题。
  • 损坏似乎是一个坏名字,因为功能与碰撞检测有关而不是损坏 - 不会碰到更好吗?