如何在 Java 中制作一个能够访问其值的对象 ArrayList



所以我正在用Java做一个游戏,我对应该如何做某事有点困惑。这是一款集换式卡牌游戏,有点像万智牌,所以到目前为止,我已经上课了

  • 游戏驱动程序
  • 狼卡
  • 拉里昂卡

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

我的游戏驱动程序类中有以下代码:

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

每张卡都扩展了卡牌,卡牌扩展了游戏驱动程序,上面的代码将打印出类似以下内容:

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

但是现在,如果我想抓住TheLarionCard的健康,我想我可以在最后一行添加.health,例如:

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

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

任何帮助都很棒!谢谢!

我认为您有三个选择:

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

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

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

    这样,编译器就知道在 TheLarionCard 类中查找 health 属性,而不是 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
        }
    }
    

    这是抽象工厂模式设计的简化版本,其他一些答案正在讨论,所以如果你不熟悉接口,你可以尝试这种方式,看看结构是否有效,然后稍后添加接口。

定义一个接口或抽象方法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;
  }
}

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

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

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

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

然后你可以创建从卡牌类继承的单独类(顺便说一句,最好重命名为"卡"),比如如果你有效果类型卡(如MTG魔法耀斑或丑陋面孔等效物),然后你也有生物卡(如MTG的Shivan Dragon或Dragon Whelp),你可以制作诸如EffectCard之类的类,它可能有自己的字段,如"持续时间"和"受影响的类型",然后用它来制作ManFlare实例、丑陋面孔实例等。还可以制作一张生物卡,其中包含生命值,第一击等内容,并从中制作ShivanDragon实例和DragonWhelp实例。

也不要害怕构图。与其为每张卡进行子类化/创建额外的类,不如像上面那样创建一个更简单的层次结构,并向其传递"命令"或"操作"类,以指示更具体的细节。就像EffectCard类的FirstStrike实例可以用一个"action"实例初始化,该实例具体告诉它如何影响CreatureCard实例一样,CreatureCard类的ShivanDragon实例将有一个动作,告诉它如何通过使用Red Lands卡等来增加攻击。

最新更新