Почему "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());
    }

}
Другие вопросы по тегам