1

I am having a terrible time with using an ArrayList in a superclass. The ArrayList is used to hold objects of three different types of subclasses of superclass Enemy. Depending on how I reference an object in the ArrayList in the driver file dictates different results.

Enemy is a child of a superclass called fighter. Fighter holds the private data for all of the objects.

Here is the superclass Enemy.

import java.util.*;

public class Enemy extends Fighter {
    public void getRandomEnemy(){};
    public ArrayList<Enemy> enemy = new ArrayList<Enemy>();

    Enemy(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
    {
        super(wep,arm,nam,health,magResis, physResis,rangResis);
    }
}

For Example:

Two of Enemy's subclasses Troll and Sorcerer have objects of their respective types added to the ArrayList found in the parent class Enemy.

Troll and Sorcerer Constructors:

Sorcerer(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
    {
        super(wep,arm,nam,health,magResis, physResis,rangResis);
    }

Troll(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
    {
        super(wep,arm,nam,health,magResis, physResis,rangResis);
    }

I am adding objects to the ArrayList in superclass enemy through these methods. Each method is found in its respective class.

public void getRandomEnemy()
    {
        enemy.add(new Troll("Bow", "Leather", "Troll",350, 30, 15,30));
    }

public void getRandomEnemy()
    {
        enemy.add(new Sorcerer("Staff", "Cloth", "Sorcerer",300, 70, 5,5));

    }

Now in my driver file if I add objects of types troll and sorcerer to the ArrayList in enemy as such.

Driver file:

int p = 5; // adds 5 enemies to the ArrayList enemy
int randEnemy = 0;
        for(int i =0; i < p; ++i)
        {

            randEnemy = (int) (Math.random() * (3));

            if(randEnemy == 0)
            {
                sorc.getRandomEnemy();
            }
            else if(randEnemy == 1)
            {
                trol.getRandomEnemy();
            }
            else
            {
                og.getRandomEnemy();
            }
        }

This is where I begin to run into issues. For example, if I want to return the size of ArrayList enemy. The total size I have to do this in my driver file.

int size = sorc.enemy.size() + trol.enemy.size() + og.enemy.size();

I have to call each specific object type and add them together.

If I do Enemy.enemy.size(); It will return 0.

Again, things get fishy with the ArrayList when I want to attack an enemy.I have to specifically look for each Sorc object or Troll object in the ArrayList.

for(Enemy j : sorc.enemy)
                {   
                    System.out.println("Sorc's Health: " + j.getHealth());
                    System.out.println("Sorc's Armor: "+ j.getArmor());
                    sorc.takeDamage(attack, "Cloth", weapon);
                }

If I do the code above I will get the correct health for the Sorcerer which is 300 and I will get the correct armor. But, the Sorcerer will not take any damage.

If I do this:

for(Enemy j : sorc.enemy)
                {   
                    System.out.println("Sorc's Health: " + j.getHealth());
                    System.out.println("Sorc's Armor: "+ j.getArmor());
                    j.takeDamage(attack, "Cloth", weapon);
                }

The health will return -1999234 or some random negative value,but the takeDamage() method will work perfectly.

My question is why when I reference the object differently, I get different results? How do I properly reference the objects in the ArrayList to ensure the proper values are getting set? I am sure it isn't a logic error because I am setting the values in the constructors and calling the constructors in the getRandomEnemy() method to add objects to the ArrayList.

EDIT: Issue Fixed

In the superclass Fighter the constructor is defined as such.

public Fighter(String wep, String arm, String nam, int health, int magResis, int physResis, int rangResis)
    {
        this.name = nam;
        this.weapon = wep;
        this.armor = arm;
        this.health = health;
        this.magicResistance = magResis;
        this.physicalResistance = physResis;
        this.rangedResistance = rangResis;
    }

Health was giving me the issue. It was the only variable turning out wonky data. As you see, the parameter has int health, and I am setting that argument that is passed through to this.health = health;

Even though I am using this. to distinguish between the the parameter and the instance variable, the value was coming out negative.

I simply changed the constructor to this:

public Fighter(String wep, String arm, String nam, int hea, int magResis, int physResis, int rangResis)
    {
        this.name = nam;
        this.weapon = wep;
        this.armor = arm;
        this.health = hea;
        this.magicResistance = magResis;
        this.physicalResistance = physResis;
        this.rangedResistance = rangResis;
    }

and now everything works.

28
  • 4
    Please show a short but complete program demonstrating the problem - you haven't provided enough information for us to help you yet. Commented Mar 30, 2015 at 13:35
  • 1
    Please provide the constructor for Troll. Commented Mar 30, 2015 at 14:02
  • 1
    There are two problems with posting snippets of your actual program, rather than a short but complete program that shows the problem: you will keep getting requests for more pieces, and you are missing out on an opportunity to find the bug yourself by seeing what you need to reproduce it. Commented Mar 30, 2015 at 14:12
  • 1
    @JasonC I apologize and I am working on it. I'll get more detailed and make a short program. Commented Mar 30, 2015 at 14:12
  • 1
    @JasonC You're right, I am not asking a specific enough question. I appreciate you all being nice to me despite botching the question. I'll try and fix it. I guess I am just confusing myself on what dictates a short and complete program. Short enough for you all to run it? I am assuming so, I'll fix it. Commented Mar 30, 2015 at 14:22

1 Answer 1

5

I think your problem is a misunderstanding of how the members of a super class work.
When you declared:

public class Enemy extends Fighter {
    public ArrayList<Enemy> enemy = new ArrayList<Enemy>();
}

Every object of type Enemy or a subclass of Enemy will have their own instance of the enemy List. They will not share the same list.
Also you are mixing up different object members:

Sourcerer sourcer = new Sourcerer();
sourcer.getHealth(); // this is a member of the object just created;
sourcer.enemy;  // is a list of Enemy type objects
                // this list is a member of the sourcer object

for(Enemy enemy : sourcer.enemy) {
      enemy; //is an object in the list
            //this object should not be sourcer object (see below)
}

sourcer.enemy.add(sourcer); //is valid but will make a really big mess
                            //so make sure you never do this. 

If you want your objects to share the same list from the super class, you need to declare it static.
I would suggest you make a separate class which manages the battle and have the list there. This way you separate the individual characters (Fighters, Enemies, Sorcerer, Trolls) from the management of groups of characters (battle).

Sign up to request clarification or add additional context in comments.

4 Comments

I see what you are saying and thank you for your help. But, is there any reason why depending on how I referenced the ArrayList the results were different or why the values are being set?
@TheDude1142 Add some temporary debugging printouts to your various methods, or even better, step through it one line at a time in your debugger (if you're using e.g. Eclipse or NetBeans). This will let you follow exactly what is happening in both cases. Tip: Give each of your objects a unique name and print it (or at least this.getClass().getSimpleName()) in your trace print-outs to help you identify what is being called on what.
@JasonC You're the man JasonC. I learn more and more each day.
I expanded the answer to clarify why you see the different results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.