You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java RPG游戏中从ArrayList访问子类并在ListView显示名称的问题

解决方案

核心问题分析

  1. 静态变量导致的name获取错误:你把name定义成了static变量,静态变量属于类而非实例。当用父类Enemy的引用指向子类实例时,访问的永远是父类的static name,而非子类的。
  2. ListView默认显示对象地址:ListView会默认调用对象的toString()方法,而默认的toString()返回的是类名+内存地址,所以你看到了com.example.test.Swordsman@x这类内容。

步骤1:修正Enemy类的设计(关键)

把所有静态成员改为实例成员,让每个敌人实例拥有自己的属性,子类通过构造方法初始化自身属性:

Enemy父类:

public class Enemy {
    protected String name = "Enemy";
    
    protected int damage = 1;
    protected int hp = 1;
    protected int defense = 1;
    protected int mana = 1;
    protected int speed = 1;
    protected int luck = 1;

    // 重写toString(),直接返回name,方便ListView显示
    @Override
    public String toString() {
        return this.name;
    }
}

Swordsman子类:

public class Swordsman extends Enemy {
    public Swordsman() {
        // 初始化子类独有的属性值
        this.name = "Swordsman";
        this.damage = 3;
        this.hp = 15;
        this.defense = 2;
        this.mana = 1;
        this.speed = 1;
        this.luck = 15;
    }
}

Archer子类(同理):

public class Archer extends Enemy {
    public Archer() {
        this.name = "Archer";
        // 填入Archer对应的属性值
        this.damage = 4;
        this.hp = 10;
        // ...其他属性
    }
}

步骤2:优化ListView显示(两种可选方式)

方式1:利用重写的toString()(最简单)

因为已经在Enemy类里重写了toString()返回name,所以你原来的添加代码只需小改,ListView会自动显示敌人的名称:

public void battle() {
    if (!prep) {
        ArrayList<Enemy> classes = new ArrayList<>();
        classes.add(new Swordsman());
        classes.add(new Archer());

        Random random = new Random();
        for (int i = 0; i < 3; i++) {
            // 随机选一个敌人添加到ListView
            int randomIndex = random.nextInt(classes.size());
            battleOptions.getItems().add(classes.get(randomIndex));
        }
        prep = true; // 标记prep为true,避免重复添加
    }
}

方式2:自定义CellFactory(更灵活,适合复杂显示)

如果之后需要显示更多信息(比如敌人的HP、伤害),可以用CellFactory自定义ListView的显示内容:

// 在初始化ListView的地方设置CellFactory
battleOptions.setCellFactory(listView -> new ListCell<Enemy>() {
    @Override
    protected void updateItem(Enemy enemy, boolean empty) {
        super.updateItem(enemy, empty);
        if (empty || enemy == null) {
            setText(null);
        } else {
            // 自定义显示内容,比如"剑士 (HP:15)"
            setText(enemy.name + " (HP:" + enemy.hp + ")");
        }
    }
});

额外优化建议

  • 把自定义的randomnumber方法替换成Java标准的Random类,更可靠:new Random().nextInt(2)就能生成0或1的随机数。
  • 子类的属性值如果是比例(比如原来的0.3),可以改成具体数值(比如3),更符合RPG游戏的数值逻辑,或者保留double类型但统一单位。

内容的提问来源于stack exchange,提问作者Real Darkflare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:35:34