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

Java Zuul世界文本冒险游戏:setState方法静态上下文引用错误

解决方案

核心问题分析

你遇到的错误是因为**Player.setState()是实例方法**,但你在ImmobileState、InjuredState、HealthyState里直接通过类名调用(静态调用方式),Java不允许从静态上下文引用非静态方法。状态类需要持有当前Player实例的引用,才能正确调用其setState方法。

具体修改步骤

1. 修改PlayerState接口,添加Player参数

让状态的heal和injure方法接收当前Player实例,这样状态类就能操作对应的玩家对象:

public interface PlayerState {
    void heal(Player player);
    void injure(Player player, int damage);
    String getState();
}

2. 修改三个状态实现类

修正构造方法语法(构造方法不能带void),并在方法中使用传入的Player实例调用setState:

ImmobileState修改后:
public class ImmobileState implements PlayerState{
    // 构造方法不能加void
    public ImmobileState(){}
    
    @Override
    public void heal(Player player){
        System.out.println("Player is now healthy");
        player.setState(new HealthyState());
    }
    
    @Override
    public void injure(Player player, int damage){
        System.out.println("You were already immobile, so nothing happened?");
        // 保持当前状态,无需修改
        // player.setState(this);
    }
    
    @Override
    public String getState(){return "Immobile";}
}
InjuredState修改后:
public class InjuredState implements PlayerState{
    public InjuredState(){}
    
    @Override
    public void heal(Player player){
        System.out.println("You are now healthy");
        player.setState(new HealthyState());
    }
    
    @Override
    public void injure(Player player, int damage) {
        if (damage == 0) {
            System.out.println("Nothing happened...");
            player.setState(new HealthyState());
        } else {
            System.out.println("You are now immobile");
            player.setState(new ImmobileState());
        }
    }

    @Override
    public String getState(){return "Injured";}
}
HealthyState修改后:
public class HealthyState implements PlayerState{
    public HealthyState(){}
    
    @Override
    public void heal(Player player){
        // 健康状态下 healing 无操作,可留空或提示
        System.out.println("You're already in perfect health!");
    }
    
    @Override
    public void injure(Player player, int damage){
        if(damage <= 10 && damage > 0) {
            System.out.println("You are now injured");
            player.setState(new InjuredState());
        }else if(damage == 0){
            System.out.println("Nothing happened...");
            player.setState(new HealthyState());
        }
        else {
            System.out.println("You are now immobile");
            player.setState(new ImmobileState());
        }
    }
    
    @Override
    public String getState(){return "Healthy";}
}

3. 修改Player类

  • 构造方法中初始化默认状态(避免state为null导致空指针异常)
  • 调用状态方法时传入当前Player实例(this)
  • 修正拼写错误healtj为health
public class Player {
    private PlayerState state;

    public Player(){
        // 初始化默认状态为健康
        this.state = new HealthyState();
    }

    public void setState(PlayerState state) {
        this.state = state;
    }
    
    public void heal(){
        state.heal(this);
    }
    
    public void injure(int damage){
        state.injure(this, damage);
    }
    
    public String showStatus(){
        StringBuilder longStatus = new StringBuilder("> Status of the Player");
        // 修正拼写错误:healtj -> health
        longStatus.append("\nhealth state: "+ state.getState());
        return longStatus.toString();
    }
}

4. 额外修正点

  • 所有状态类的构造方法都不能加void,之前的写法会被当成普通方法而非构造方法
  • ImmobileState的injure方法中原来的Player.setState()无参数调用是错误的,现在改为保持当前状态(或直接不修改)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 17:05:31