Почему "instanceof" не работает?
Я использую экземпляр Java, но он не работает.
У меня есть три Java-класса, которые расширяют класс Hero.
Класс Hero.java:
public abstract class Hero {
protected int health;
public Hero() {
}
}
Другие три класса:
public class Archer extends Hero {
public Archer() {
}
}
public class Mage extends Hero {
public Mage() {
}
}
public class Warrior extends Hero {
public Warrior() {
}
}
У меня есть этот основной класс WelcomeScreen.java
public class WelcomeScreen {
private Archer archer;
private Mage mage;
private Warrior warrior;
private Hero hero;
public WelcomeScreen() {
// choose a hero (archer/mage/warrior)
hero = archer;
new Game(hero);
}
public static void main(String args[]) {
new WelcomeScreen();
}
}
который создает класс Game.java
public class Game {
public Game(Hero chosenHero) {
if (chosenHero instanceof Mage) {
System.out.println("you selected mage");
} else if (chosenHero instanceof Archer) {
System.out.println("you selected archer");
} else if (chosenHero instanceof Warrior) {
System.out.println("you selected warrior");
} else {
System.out.println("you selected NOTHING");
}
}
}
В Game.java код предназначен для проверки того, является ли selectedHero объектом Archer.java, Warrior.java или Mage.java, но я получаю "вы НИЧЕГО не выбрали". Почему instanceof не может проверить, назначил ли я его Archer.java в WelcomeScreen?
2 ответа
Потому что ваши константы null
, Когда ты сказал,
private Archer archer;
это эквивалентно
private Archer archer = null;
Кроме того, вы создали три поля для каждого экземпляра. Я думаю, что вы хотели сделать что-то вроде
private static final Hero archer = new Archer();
private static final Hero mage = new Mage();
private static final Hero warrior = new Warrior();
Смотрите также Что означает "программировать на интерфейс"?
Альтернативное решение: избавьтесь от instanceof, поскольку он предлагает хрупкую жесткую конструкцию, которую легко сломать. Вместо этого попробуйте использовать другие более ООП-совместимые решения, такие как наследование или, если сложный, шаблон проектирования посетителя.
Например, простая структура наследования может выглядеть примерно так:
public class WelcomeScreen {
public WelcomeScreen() {
// choose a hero (archer/mage/warrior)
Hero hero = new Archer();
new Game(hero);
}
public static void main(String args[]) {
new WelcomeScreen();
}
}
abstract class Hero {
protected int health;
// other shared fields such as String name,...
public Hero() {
}
public abstract String getType();
public int getHealth() {
return health;
}
}
class Archer extends Hero {
public static final String TYPE = "Archer";
public Archer() {
}
@Override
public String getType() {
return TYPE;
}
}
class Mage extends Hero {
public static final String TYPE = "Mage";
public Mage() {
}
@Override
public String getType() {
return TYPE;
}
}
class Warrior extends Hero {
public static final String TYPE = "Warrier";
public Warrior() {
}
@Override
public String getType() {
return TYPE;
}
}
class Game {
private Hero hero;
public Game(Hero chosenHero) {
this.hero = chosenHero;
System.out.println("You selected a hero of type " + hero.getType());
}
}