为什么 "instanceof" 不起作用?

Why is "instanceof" not working?

我正在使用 Java instanceof 但它似乎不起作用。

我有 三个 java class扩展英雄 class。
Hero.java class:

public abstract class Hero {

    protected int health;

    public Hero() { 
    }
}

另外三个classes:

public class Archer extends Hero {
    public Archer() {
    }
}

public class Mage extends Hero {
    public Mage() {
    }
}

public class Warrior extends Hero {
    public Warrior() {
    }
}

我有这个主classWelcomeScreen.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 class

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中,代码是为了检查chosenHero是否是Archer.java的对象, Warrior.java,或Mage.java,但我的结果是"you selected NOTHING".为什么 instanceof 无法检查我是否已在 WelcomeScreen 中将其分配给 Archer.java

因为你的常量是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();

另见 What does it mean to “program to an interface”?

替代解决方案:摆脱 instanceof,因为它暗示了一种脆弱的刚性设计,一种很容易损坏的设计。相反,尝试使用其他更符合 OOP 的解决方案,例如继承,或者如果复杂,则使用访问者设计模式。

例如,一个简单的继承结构可能类似于:

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());
    }

}