如何使用Java访问其值的对象的ArrayList

时间:2012-08-18 23:03:19

标签: java class object arraylist

所以我正在开发一个Java游戏,我对如何处理某些事情感到有些困惑。这是一个交易卡游戏,有点像魔术,所以到目前为止,我有类

  • GameDriver
  • WolfCard
  • TheLarionCard

我希望我能够拥有至少50种不同类型的卡片,每张卡片都在他们自己的课堂上,所以有一个小问题,这是最好的方法吗?至于我的问题:

我的GameDriver类中有以下代码:

ArrayList<Cards>  playerHand = new ArrayList<Cards>();
playerHand.add(new WolfCard());
playerHand.add(new TheLarionCard());
System.out.println(((Cards)playerHand.get(1)));

每张卡都扩展了卡片,卡片扩展了GameDriver,上面的代码将打印出类似的内容:

TheLarionCard[panel0,0,0,0x0,invalid,layout=java.awt.FlowLayout]

但现在,如果我想抓住说TheLarionCard的健康状况,我想我可以将.health添加到最后一行,如:

System.out.println(((Cards)playerHand.get(1).health));

但显然我不能,我在这里做错了什么?

任何帮助都很棒!谢谢!

4 个答案:

答案 0 :(得分:3)

我认为你有三种选择:

  1. 您希望每种不同类型的卡都具有health属性。在这种情况下,您可以将该属性放入父类Cards中,然后向任何扩展Cards的类请求属性是有效的。如果Cards类具有health数据字段,则问题中的代码将起作用。

  2. 您只希望TheLarionCard拥有健康属性。在这种情况下,您的演员阵容将是:

    System.out.println(((TheLarionCard)playerHand.get(1).health));
    

    这样,编译器就知道要在TheLarionCard类中查找健康属性,而不是Cards类。

  3. 您实际上并不需要将单个卡类作为Cards的子类。如果没有真正令人信服的理由你就这样做了,那么你可以让所有卡成为Cards类的一部分,并且可以通过数据字段指定它们的不同类型(TheLarionCard,WolfCard等)。例如:

    public class Card {
        String type;
    
        public Card(String inType) {
            this.type = inType;
        }
    
        public String toString() {
            return "This is a " + type;
        }
    }
    

    这样,如果您希望不同的卡的行为不同,您可以检查其type值并根据其值分配不同的行为,例如

    public void awesomeMethod() {
        if ("TheLarionCard".equals(type)) {
            // execute TheLarionCard code
        } else if ("WolfCard".equals(type)) {
            // execute WolfCard code
        }
    }
    

    这是Abstract Factory Pattern设计的简化版本,其他一些答案正在讨论,所以如果您是接口的新手,可以通过这种方式尝试查看结构是否有效,然后添加接口后面。

答案 1 :(得分:1)

getHealth()中定义接口或抽象方法Cards方法,必须由WolfCardTheLarionCard实施。然后,您可以playerHand.get(1).getHealth()

例如:

public abstract class BaseCard {
  protected int health;

  public abstract int getHealth();
}

public class WolfCard extends BaseCard {
  private int wolfHealthBoost;  

  public int getHealth() {
    return health + wolfHealthBoost;
  }
}

public class TheLarionCard extends BaseCard {
  public int getHealth() {
    return health;
  }
}

答案 2 :(得分:0)

您应检查这些类中是否具有健康属性的getter,无法从类外部访问私有属性。

只需创建一个返回健康属性的新方法getHealth(),然后将其追加到最后一行的点后面。

顺便说一句,如果您已经使用该构造型定义了ArrayList,则不必转换Cards类。

答案 3 :(得分:0)

你真的不需要接口甚至是如此复杂的类。我猜你所有的卡都有类似的行为。它们属于某种类型,可以执行特定操作,可以对它们执行操作和/或影响等等。因此,您只需要一个卡类,并且其中包含管理这些通用状态的所有字段和方法/动作。

然后你可以创建从Cards类继承的单独的类(顺便说一句,最好重命名为“Card”),就好像你有效果类型的牌(比如MTG Mana Flare或Hideous Visage等价物)然后你也有生物牌(比如MTG的Shivan Dragon或Dragon Whelp)你可以制作像EffectCard这样的类,它可能有自己的字段,如“duration”和“affectedTypes”,然后用它来制作ManFlare实例,Hideous Visage实例等。同时使用hitpoints,firstStrike等东西制作一个CreatureCard,并从中制作ShivanDragon实例和DragonWhelp实例。

也不要害怕构图。不是为每张卡子类化/制作额外的类,而是制作一个比上面更简单的层次结构,并传递“命令”或“动作”类,它们决定了更具体的细节。就像EffectCard类的FirstStrike实例可以使用“action”实例初始化,该实例告诉它具体如何影响CreatureCard实例,CreatureCard类的ShivanDragon实例将有一个动作告诉它如何通过利用Red来增加它的攻击土地卡等