Java:Superclass中的ArrayList

时间:2015-03-30 13:33:10

标签: java arraylist

我在超类中使用ArrayList时遇到了可怕的时间。 ArrayList用于保存超类Enemy的三种不同类型子类的对象。根据我在驱动程序文件中引用ArrayList中的对象的方式决定了不同的结果。

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);
    }
}

例如:

Enemy的两个子类Troll和Sorcerer将各自类型的对象添加到父类Enemy中的ArrayList中。

巨魔和巫师构造者:

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);
    }

我通过这些方法将对象添加到超类敌人的ArrayList中。每种方法都可以在各自的类中找到。

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));

    }

现在在我的驱动文件中,如果我将类型为troll和sorcerer的对象添加到敌人的ArrayList中。

驱动程序文件:

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();
            }
        }

这是我开始遇到问题的地方。 例如,如果我想返回ArrayList敌人的大小。我必须在驱动程序文件中执行此操作的总大小。

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

我必须调用每个特定的对象类型并将它们一起添加。

如果我做Enemy.enemy.size();它将返回0。

再次,当我想攻击敌人时,使用ArrayList的事情变得可疑。我必须专门在ArrayList中查找每个Sorc对象或Troll对象。

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);
                }

如果我执行上面的代码,我将获得300的Sorcerer正确的健康状况,我将获得正确的护甲。但是,巫师不会受到任何伤害。

如果我这样做:

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);
                }

运行状况将返回-1999234或一些随机负值,但takeDamage()方法将完美运行。

我的问题是为什么当我以不同方式引用对象时,我会得到不同的结果?如何正确引用ArrayList中的对象以确保设置正确的值?我确信这不是逻辑错误,因为我在构造函数中设置值并在getRandomEnemy()方法中调用构造函数以将对象添加到ArrayList。

编辑:问题已修复

在超类战斗机中,构造函数被定义为。

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;
    }

健康问题给了我这个问题。这是唯一可变数据的变量。如您所见,该参数具有int health,我将该参数设置为传递给this.health = health;

即使我正在使用它。为了区分参数和实例变量,该值是负面的。

我只是将构造函数更改为:

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;
    }

现在一切正常。

1 个答案:

答案 0 :(得分:5)

我认为你的问题是对超级成员的工作方式的误解 当你宣布:

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

Enemy类型的每个对象或Enemy的子类都将拥有自己的enemy列表实例。他们不会共享相同的名单 你也混合了不同的对象成员:

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. 

如果你想让你的对象从超类中共享相同的列表,你需要声明它static
我建议你创建一个单独的类来管理战斗并在那里列出。这样你就可以将各个角色(战士,敌人,巫师,巨魔)与角色组(战斗)的管理分开。