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
相关产品推荐
相关产品推荐

