How to make an ArrayList of objects in Java with the ability to access their values

15,892

Solution 1

I think you have three options:

  1. You want each different type of card to have a health property. In this case, you can put that property into the parent class Cards and then it will be valid to ask for the property for any class that extends Cards. If the Cards class has a health data field, the code in your question will work.

  2. You want only TheLarionCard to have a health property. In that case, your cast would have be:

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

    This way, the compiler has knows to look in the TheLarionCard class for the health property, not the Cards class.

  3. You don't actually need the individual card classes to be subclasses of Cards. If there's no really compelling reason you've done it that way, you could have all cards be part of the Cards class and their different types (TheLarionCard, WolfCard, etc) could be designated by a data field. For example:

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

    This way if you want the different cards to behave differently, you can check their type value and assign different behaviors based on its value, e.g.

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

    This is a simplified version of the Abstract Factory Pattern design that some of the other answers were talking about, so if you're new to interfaces you could try it this way to see if the structure works, then add interfaces later.

Solution 2

Define an interface or abstract method getHealth() method in Cards, that must be implemented by WolfCard and TheLarionCard. Then, you can do playerHand.get(1).getHealth().

For instance:

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;
  }
}
Share:
15,892
Jeremy Sayers
Author by

Jeremy Sayers

Updated on June 05, 2022

Comments

  • Jeremy Sayers
    Jeremy Sayers almost 2 years

    so I'm working on a game in Java, and I'm a little confussed on how I should go about something. It's a Trading Card Game, kinda like Magic, and so for classes so far I have

    • GameDriver
    • Cards
    • WolfCard
    • TheLarionCard

    It is my hope that I'll be able to have atleast 50 different types of card, each of which in their own class, so a little side question is, is this the best way? As for my problem:

    I have the following code inside my GameDriver class:

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

    Each card extends Cards, and Cards extend GameDriver, The code above will print out something like:

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

    But now, if I want to grab the health of say TheLarionCard, I thought I could just add .health to the last line like:

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

    But obviously I can't, what am I doing wrong here?

    Any help is great! Thank you!