我在超类中使用ArrayList时遇到了可怕的时间.ArrayList用于保存超类Enemy的三种不同类型子类的对象.根据我在驱动程序文件中引用ArrayList中的对象的方式决定了不同的结果.
敌人是一个叫做战士的超级孩子.战斗机保存所有对象的私人数据.
这是超级敌人.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
例如:
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);
}
Run Code Online (Sandbox Code Playgroud)
我通过这些方法将对象添加到超类敌人的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));
}
Run Code Online (Sandbox Code Playgroud)
现在在我的驱动文件中,如果我将类型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();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我开始遇到问题的地方.例如,如果我想返回ArrayList敌人的大小.我必须在驱动程序文件中执行此操作的总大小.
int size = sorc.enemy.size() + trol.enemy.size() + og.enemy.size();
Run Code Online (Sandbox Code Playgroud)
我必须调用每个特定的对象类型并将它们添加到一起.
如果我做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);
}
Run Code Online (Sandbox Code Playgroud)
如果我执行上面的代码,我将获得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);
}
Run Code Online (Sandbox Code Playgroud)
运行状况将返回-1999234或一些随机负值,但takeDamage()方法将完美运行.
我的问题是为什么当我以不同方式引用对象时,我会得到不同的结果?如何正确引用ArrayList中的对象以确保设置正确的值?我确信这不是逻辑错误,因为我在构造函数中设置值并在getRandomEnemy()方法中调用构造函数以将对象添加到ArrayList.
编辑:问题已修复
在超类Fighter中,构造函数被定义为这样.
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;
}
Run Code Online (Sandbox Code Playgroud)
健康问题给了我这个问题.这是唯一可变数据的变量.如您所见,该参数具有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;
}
Run Code Online (Sandbox Code Playgroud)
现在一切正常.
我认为你的问题是对超级班的成员如何运作的误解.
当你宣布:
public class Enemy extends Fighter {
public ArrayList<Enemy> enemy = new ArrayList<Enemy>();
}
Run Code Online (Sandbox Code Playgroud)
每个类型的对象Enemy或子类都Enemy将拥有自己的enemyList 实例.他们不会共享相同的列表.
你也混合了不同的对象成员:
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.
Run Code Online (Sandbox Code Playgroud)
如果希望对象从超类共享相同的列表,则需要声明它static.
我建议你组建一个单独的班级来管理战斗并在那里列出清单.通过这种方式,您可以将各个角色(战士,敌人,魔法师,巨魔)与角色组(战斗)的管理分开.