从每个子类中的超类静态初始化变量

时间:2015-11-06 18:52:20

标签: java static

我想创建一个名为Unit的抽象超类,并为其提供一些受保护的静态字段,例如name,health,attackPower等。

public abstract class Unit {
    protected static String name;
    protected static int maxHealth;
    protected static int atkPower;

    public String getName() {
        return name; 
    }
}

然后我想创建几个子类,例如Soldier,Wizard和Tank,并在每个类中静态分配受保护的字段,以便所有士兵具有相同的字段值,所有向导都具有相同的字段值,并且所有坦克具有相同的字段值。我试过这样的事情:

public class Soldier extends Unit {
    static {
        name = "Soldier";
        maxHealth = 80;
        atkPower = 15;
    }
}

public class Wizard extends Unit {
    static {
        name = "Wizard";
        maxHealth = 60;
        atkPower = 25;
    }
}

如果我创建一个向导对象,向导,然后调用wizard.getName()我得到“向导”。但是,如果我然后创建一个Soldier对象,士兵,调用wizard.getName()会返回“Soldier”。士兵对象静态地覆盖向导和士兵类中的变量值。

Wizard wizard = new Wizard();
wizard.getName(); //Wizard
Soldier soldier = new Soldier();
wizard.getName(); //Soldier

有没有办法做我想做的事情,那就是为每个子类中的同一个变量保留不同的静态值?

2 个答案:

答案 0 :(得分:1)

正确的方法是恕我直言getName()(同样适用于健康等)abstract

public abstract class Unit {    
    public abstract String getName();
}

public class Wizard extends Unit {

    private static final String NAME = "Wizard";

    @Override
    public String getName() { 
        return NAME; 
    }
}

答案 1 :(得分:0)

不要让成员保持静态。制作子类必须为每个字段覆盖的抽象方法。这样,您还可以限制对不应再次set的字段的访问,并且只能在get上下文中访问:

public abstract class Unit {
    public void battleCry() {
        System.out.println("RAWR! I am a " + name() + 
            "! Tremble at my " + atkPower() + 
            " attack points!");
    }

    public abstract String name();
    public abstract int maxHealth();
    public abstract int atkPower();
}

然后子类覆盖这些:

public class Wizard extends Unit {
    protected final String name = "Wizard";

    @Override
    public String name() {
        return name;
    }

    @Override
    public int maxHealth() {
        return 60;
    }

    @Override
    public int atkPower() {
        return 25;
    }
}

这使得更多子类更容易覆盖这些方法:

public class BossWizard extends Wizard {
    @Override
    public String name() {
        return "Boss" + super.name();
    }

    @Override
    public int maxHealth() {
        return super.maxHealth() * 2;
    }

    @Override
    public int atkPower() {
        return super.atkPower() * 2;
    }

    public void specialAtk() {
        // Something special for the BossWizard
    }
}

如果您分别有WizardBossWizard的实例,现在可以看到,该战斗是不同的:

wizardInstance.battleCry();     // RAWR! I am a Wizard! Tremble at my 60 attack points!
bosswizardInstance.battleCry(); // RAWR! I am a BossWizard! Tremble at my 120 attack points!