我在超类中使用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;
}
现在一切正常。
答案 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
。
我建议你创建一个单独的类来管理战斗并在那里列出。这样你就可以将各个角色(战士,敌人,巫师,巨魔)与角色组(战斗)的管理分开。