首页 > 解决方案 > 如何检查哪个子类被传递到构造函数中?

问题描述

我对 Java 和编程比较陌生,所以如果这个问题看起来很愚蠢,我深表歉意。我正在为 Java 编程类创建一个战斗游戏——我有一个带有一些基本方法的 Hero 类和一个扩展 Hero 但添加了自己独特方法的子类 Paladin。我想要一个可以传入 ANY 的 Battleground 对象Hero 类,然后检查传入了哪个特定子类。如何确定传入了哪些 Hero 子类?

public class Hero {

  private String name;
  private int hitPoints;

  public Hero (String name, int hitPoints) {
     this.name = name;
     this.hitPoints = hitPoints;
  }

  public String getName() { return this.name; }

  public int getHitPoints() { return this.hitPoints; }

  public void takeDamage(int amount) { this.hitPoints -= amount; }
}

这是圣骑士班

public class Paladin extends Hero {

  public Hero (String name, int hitPoints) {
    super(name, hitPoints);
  }

  public void heal(int amount) {
    this.hitPoints += amount;
  }
}

所以在战场类中,我有一个方法尝试(错误地)检查传入的英雄是否是圣骑士。我该怎么做呢?if 语句是一个占位符伪代码,只是为了澄清我的意思。

public class Battleground {

  private Hero player;

  public Battleground (Hero player) {
    this.player = player;
  }

  public void startRound() {
    // HERE!!
    if (player.equals(Paladin)) {
      player.heal();
    }
  }
}

标签: java

解决方案


考虑到你的职业实际上是在建模什么,战场知道圣骑士在回合开始时会治愈自己,或者战场负责确保圣骑士治愈自己,这没有多大意义。

更明智的设计是让游戏通知英雄该回合已经开始,并让特定的Hero子类控制该回合开始时该英雄的行为。例如:

public class Hero {
    // ...

    public void onRoundStart() {
        // do nothing
    }
}
public class Paladin extends Hero {
    // ...

    @Override
    public void onRoundStart() {
        // your heal method takes an int as its argument
        heal(10);
    }
}
public class Battleground {
    // ...

    public void startRound() {
        // let the particular Hero subclass control what happens
        player.onRoundStart();

        // ...
    }
}

这样您就不需要任何if语句或instanceof检查,而且定义 Paladin 行为的代码也位于Paladin它所属的类中。如果您以后想更改圣骑士的规则,将更容易知道您需要编辑哪个类。

这种重构被称为“用多态替换条件”。


推荐阅读