【问题标题】:Java - passing ArrayList of interface typeJava - 传递接口类型的ArrayList
【发布时间】:2012-05-23 02:07:46
【问题描述】:

我有一个Damageable接口如下

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 不允许我在 body 类型为 ArrayList 且 BaseObject 实现 Damageable 的情况下执行 new CollisionManager(bodies)

我尝试过投射。说不能从 ArrayList&lt;BaseObject&gt; 到 ArrayList 也尝试使用Class&lt;? extends Damageable&gt;,但我无法调用在接口Damageable中声明的方法。如何传递 ArrayList?

【问题讨论】:

标签: java interface arraylist


【解决方案1】:

你必须明确你的泛型。因此,您必须告知编译器您的泛型类型本身必须Damagable,而是可以扩展Damagable

public CollisionManager(ArrayList<? extends Damagable> bodies) {

顺便说一下,请注意我将您的变量更改为 bodies 而不是 _bodies。下划线不是标准 Java 编码约定的一部分。


根据 OP 的 cmets 进行编辑

假设您有一个名为Damagable具体 类,而不是接口。告诉编译器&lt;? extends Damagable&gt; 表示它不必是Damagable 的实例。 ok 类型 extend Damagable。否则,编译器会假定您有一个Damagable 正是

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

您必须记住,您使用的是 Java 类型,而不是类。 Java 的类型语法和结构不如它的类结构健壮。对于类型,没有implements 的概念。


最后一轮修改

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

因此,通过这些修订,您将拥有:

public CollisionManager(List<? extends Damagable> bodies) {

【讨论】:

  • 感谢您的回复,但 ArrayList 必须实现 Damageable,因为我正在使用该接口的方法。
  • ? extends Damagable 表示 implements Damagable 在 Java 通用语言中。
  • 让我确认一下。数组列表 extends Damageable> 表示任何类型的 ArrayList 扩展或实现了接口 Damageable 对吧?
  • 那和 ArrayList 有什么不同呢? Java 是否不知道我正在传递一个接口并且需要它背后的具体类型?
  • 虽然有点范围蔓延,但我希望这个讨论也说明了如果您只知道接口名称,如何在 for 循环中迭代 List。提示:它不是 for( ? extends Damageable x : myList )
【解决方案2】:

试试ArrayList&lt;? extends Damageable &gt; _bodies

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

【讨论】:

  • ArrayList> 和 ArrayList
  • 我在这里可能是错的,但我什么都没想。你放的那个指定它必须是一个类,并扩展/实现可损坏,但当然它无论如何都必须是一个类(我再次认为)。不过,这已接近我的泛型知识的极限。你的能编译吗?
  • ArrayList> 不可行,因为这样做不会让我调用已在接口中声明的方法。
  • @wirate 我认为您在对此答案的第一条评论中的想法是正确的,但是,您输入的内容无法编译。 ArrayList&lt;Class &lt;? extends Damageable&gt;&gt;(注意左尖括号的数量)编译,但是你会得到Class对象的列表,而不是Damagable对象的列表。
【解决方案3】:

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

我只想提几个你或许应该考虑的设计问题:

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

【讨论】:

  • 事实上,我按照您在第 1 点中的建议进行了操作。我只是保持谨慎。第 2 点:Box2D 正在检测碰撞,当检测到碰撞时,我只需要调用此类型的方法 第 3 点:在我的情况下存在碰撞但从未损坏的对象
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-20
  • 2016-02-12
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
相关资源
最近更新 更多