【问题标题】:Java List problems with Polymorphism [duplicate]多态性的Java列表问题[重复]
【发布时间】:2016-08-17 10:21:20
【问题描述】:

我想用 Java 编写一个基于文本的游戏,但遇到了一个问题。
我有一个HeadArmor 对象,extends Armorextends Item 和这个implements IEquipable
如果我将一个HeadArmor 对象添加到我的LinkedList 并尝试访问它,它就会变成一个Item 对象。

private LinkedList<Item> items = new LinkedList<Item>();

我如何将对象从列表中取出的方法。

public Item getItemByName(String name) {            
    int i = 0;
    for (Item item : items) {
        if (item.getName().equals(name)) {
            //And the output is a Item Object and no HeadArmor
            System.out.println(items.get(i).getClass().getName());
            return items.get(i);
        }           
     i++;
    }
    return null;
}

因此我无法检查我的 Object 是否是 HeadArmor 的实例。

public boolean equip(String name){
        Item item = getItemByName(name);
        //here he prints out I AM A DieWeltvonZuul.Item CLASS
        System.out.println("I AM A "+item.getClass().getName()+ " CLASS");

        if(item instanceof Weapon){
            if (null != weapon) {
                items.add(weapon);
                weapon = (Weapon) item;
            }else{
                weapon = (Weapon) item;
            }
        }else{
            //here he won't enter even the Object was at the beginning of type HeadArmor and this Object extends Armor
            if (item instanceof Armor){
                changeItem((IEquippable) getItemByName(name));
            }else{
                return false;
            }
        }
        return true;
    }

如果我尝试将它投射到 HeadArmor 上,我会得到 ​​p>

java.lang.ClassCastException: DieWeltvonZuul.Item cannot be cast to DieWeltvonZuul.HeadArmor

【问题讨论】:

  • 逻辑有问题。
  • 您使用单独的索引来访问该项目是否有任何不明显的原因。您已经在 for-each 循环中获得了正确的项目...
  • minimal reproducible example会容易很多
  • 您能添加用于创建项目的代码吗?

标签: java list polymorphism


【解决方案1】:

使用for (Item item : items) 是一个不错的选择。那你为什么要使用i?没有意义。

我不确定您想要实现什么,但让我向您展示以下代码:

public Item getItemByName(String name) { 
    for (Item item : items) {
        if (item.getName().equals(name)) {
            if (item instanceof HeadArmor) {
                return item;
            }
        }
    }
    return null;
}

您添加到List&lt;Item&gt;HeadArmor 不会变成Item。已经是Item。每个HeadArmorItemArmorHeadArmor。它也是Object。但是,List&lt;Item&gt; 中的所有对象都保证为Items(和Objects),仅此而已。如果你想检查它们是否也是ArmorHeadArmor,你必须trycast。如果casting成功,说明这个iteminstance of HeadArmor

我假设您想要的可能是以下内容:

Item i = getItemByName("helmet");
Header h = ((i == null) ? null : (HeadArmor)i);

【讨论】:

  • 你不应该对控制逻辑使用异常处理,这是一种不好的编码习惯。请改用instanceof
  • @PiotrWilkin 你是对的。已编辑。
  • @PiotrWilkin 复制我的答案推荐?
  • @Cold Fire:我赞成:>
  • 好的,只是在问
【解决方案2】:

如果我使用此代码将项目添加到列表中

items.add(new HeadArmor("helmet"));
items.add(new Armor("chain mail"));

并尝试使用您的getItemByName 方法检索helmet。正如预期的那样,输出将是HeadArmor。也许您创建项目并将项目添加到项目列表的方式存在问题?!

【讨论】:

    【解决方案3】:

    您可以使用instanceOf的方法来检查项目是否为headArmor类型

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-09
      • 1970-01-01
      • 2015-07-19
      • 1970-01-01
      • 2010-12-29
      相关资源
      最近更新 更多