2015-11-06 91 views
-1

我想創建一個抽象的超類,稱爲單位,並給它一些受保護的靜態字段,如姓名,健康,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,並且在每個類中靜態分配受保護的字段,以便所有的Soldiers具有相同的字段值,所有的Wizards具有相同的字段值,並且所有坦克具有相同的字段值。我想是這樣的:

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()我得到的「精靈」。但是,如果我然後創建一個士兵對象,士兵,調用wizard.getName()而不是返回「士兵」。士兵對象靜態地覆蓋了嚮導和士兵類中變量的值。

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

有沒有辦法做我想做的事情,即爲每個子類中的相同變量保留不同的靜態值?

+0

「不要使用靜態」是正確的。在你所說的問題的背景下,「靜態」是一個可怕的想法。使用[實例變量。](https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html) – markspace

+0

@shadowarcher是否有任何理由讓變量保持靜態? – user3437460

回答

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

現在你可以看到,如果你有Wizard和實例分別不同:

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!