Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 静态初始化每个子类中超类中的变量_Java_Static - Fatal编程技术网

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

Java 静态初始化每个子类中超类中的变量,java,static,Java,Static,我想创建一个名为Unit的抽象超类,并为它提供一些受保护的静态字段,如名称、运行状况、攻击能力等 public abstract class Unit { protected static String name; protected static int maxHealth; protected static int atkPower; public String getName() { return name; } } 然后我想创

我想创建一个名为Unit的抽象超类,并为它提供一些受保护的静态字段,如名称、运行状况、攻击能力等

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

    public String getName() {
        return name; 
    }
}
然后我想创建几个子类,如士兵、向导和坦克,并在每个类中静态分配受保护的字段,以便所有士兵都有相同的字段值,所有向导都有相同的字段值,所有坦克都有相同的字段值。我试过这样的方法:

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,然后调用Wizard.getName(),我会得到“Wizard”。然而,如果我随后创建一个士兵对象,士兵,调用wizard.getName()将返回“士兵”。士兵对象静态重写向导和士兵类中变量的值

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

有没有什么方法可以实现我想做的,那就是在每个子类中为同一个变量保留不同的静态值?

正确的方法是如何使
getName()
(对于健康状况等相同):


不要将成员设置为静态。创建子类必须为每个字段重写的抽象方法。通过这种方式,您还可以限制对不应再次设置的字段的访问,这些字段只能在
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
    }
}
现在您可以看到,如果您分别拥有
向导
BossWizard
的实例,那么战斗口号就不同了:

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!

“不要使用
静态
”是正确的。就您所述的问题而言,
static
是一个糟糕的想法。使用@shadowarcher是否有任何原因使变量保持静态?
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
    }
}
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!