【问题标题】:How to make an ArrayList of objects in Java with the ability to access their values如何在 Java 中创建一个能够访问其值的对象的 ArrayList
【发布时间】:2012-08-14 21:54:24
【问题描述】:

所以我正在使用 Java 开发一款游戏,但对于我应该如何做某事感到有些困惑。这是一个集换式卡牌游戏,有点像万智牌,所以到目前为止我有的课程

  • 游戏驱动程序
  • 卡片
  • 狼卡
  • 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));

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

任何帮助都很棒!谢谢!

【问题讨论】:

  • 是所有Cards 都继承Cardshealth 方法,还是只有TheLarionCardhealth 方法?
  • 如 pb2q 所述,但 health 是可公开评估的成员吗? (我必须是 .health() 才能成为一种方法;))

标签: java class object arraylist


【解决方案1】:

Cards中定义一个接口或抽象方法getHealth()方法,必须由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;
  }
}

【讨论】:

  • 你能再解释一下吗?我以前没有用过接口,除非我用过而且我不知道它们是什么。
  • @JeremySayers:我使用抽象基类添加了一个小的 usample。
  • 谢谢你的回答,完美地回答了我的问题,但现在我有点怀疑这是否是最好的方法,例如,我将如何抓取随机卡片来填充甲板?我应该做一门课,在里面创建卡片吗?
  • 是的,您可以创建一个 DeckBuilder,其中包含所有可能的卡片 List,然后从该列表中随机抽取 52 个元素来创建一张桌子。
  • 我最终做了什么,拥有 Driver 类和 Card 类,并且在 Card 构造函数内部我声明了健康强度等,因此在驱动程序类中我可以这样做: library.add( new Card("铁刺猬", 2, 2, 2));砰!感谢大家的帮助!
【解决方案2】:

你应该检查这些类中是否有健康属性的getter,不能从类外部访问私有属性。

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

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

【讨论】:

    【解决方案3】:

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

    然后您可以创建从 Cards 类继承的单独类(顺便说一句,最好将其重命名为“Card”),例如如果您有效果类型卡(例如 MTG Mana Flare 或 Hideous Visage 等价物),然后你也有生物卡(比如 MTG 的 Shivan Dragon 或 Dragon Whelp),你可以制作诸如 EffectCard 之类的类,它可能有自己的字段,如“duration”和“affectedTypes”,然后用它来制作 ManFlare 实例、Hideous Visage 实例等。还可以使用生命值、firstStrike 等内容制作 CreatureCard,并从中制作 ShivanDragon 实例和 DragonWhelp 实例。

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

    【讨论】:

      【解决方案4】:

      我认为你有三个选择:

      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 设计的简化版本,其他一些答案正在讨论,所以如果您不熟悉接口,您可以尝试这种方式来查看结构是否有效,然后稍后添加接口。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-04
        • 2020-11-21
        • 2015-05-04
        • 1970-01-01
        • 1970-01-01
        • 2016-10-09
        • 1970-01-01
        相关资源
        最近更新 更多