2012-01-20 35 views
1

這裏是我的情況通用<T extends A>類使用一個靜態字段,而不是T的一個

public abstract class Actions { 

    public static Actions STAND; 
    public static Actions ATTACK; 
    public static Actions COLONIZE; 
    public static Actions DEFEND; 
    public static Actions TURN_CW; 
    public static Actions TURN_CCW; 
    public static Actions DIE; 

    public abstract long[] getFramesDurations(); 
    public abstract int[] getBaseTiles(); 
} 

public class SimpleActions extends Actions{ 

    public static Actions STAND = new SimpleActions(new long[]{120,120,120,120,120,120,120}, new int[]{0,1,2,3,4,5,6}); 
    public static Actions ATTACK = new SimpleActions(new long[]{120,120,120,120,120,120,120,120,120}, new int[]{7,8,9,10,11,12,13,14,15}); 
    public static Actions COLONIZE = new SimpleActions(new long[]{120,120,120,120,120,120,120}, new int[]{7,8,9,10,11,12,13,14,15}); 
    public static Actions DEFEND = new SimpleActions(new long[]{1}, new int[]{1}); 
    public static Actions TURN_CW = new SimpleActions(new long[]{1}, new int[]{1}); 
    public static Actions TURN_CCW = new SimpleActions(new long[]{1}, new int[]{1}); 
    public static Actions DIE = new SimpleActions(new long[]{1}, new int[]{1}); 

    private final long[] mActionFramesDurations; 
    private final int[] mActionBaseTiles; 

    SimpleActions(long[] pActionFramesDurations, int[] pActionBaseTiles) { 
     mActionFramesDurations = pActionFramesDurations; 
     mActionBaseTiles = pActionBaseTiles; 
    } 

    public long[] getFramesDurations() 
    { 
     return mActionFramesDurations; 
    } 

    public int[] getBaseTiles() 
    { 
     return mActionBaseTiles; 
    } 
} 

public abstract class A<T extends Actions> { 
    A() { 
     doSomething(T.STAND); 
    } 

    protected void doSomething(Actions action) { use action somewhere} 
} 

public class B extends A<SimpleActions> { 
    B() { 
     super(); 
    } 
} 

我總是得到NullPointerException異常時,A的構造函數調用DoSomething的,因爲行動是空..

由於B延伸的我期待它使用SimpleActions.STAND,而不是Actions.STAND。

我在做什麼錯了?我應該怎麼做?

+1

您正在從類「B」調用'super()' - 在超類層次,所有編譯器都知道'T'擴展了'Actions',而不是'SimpleActions'。你有沒有考慮過爲你的行爲使用'Enum',還是需要「覆蓋」它們?如果有的話,Java不會像你期望的那樣通過Smalltalk進行靜態繼承;因爲你的代碼是,你的'Actions'類中的靜態聲明是毫無意義的。 –

回答

1

Java語言規範writes

與結合Ť& I1一個類型變量X的成員...在是的交點類型(§4.9)筆& I1的成員...在出現在聲明類型變量的地方。

這就是爲什麼表達T.STANDActions.STAND,不SimpleActions.STAND

Actions.STANDSimpleActions.STAND是不同的領域(與非靜態方法,字段不能被覆蓋。)

已經凸顯委託給子類的一種方式:定義訪問方法(吸氣),其子類必須重寫:

abstract class Actions { 
    abstract Actions stand(); 
} 

class SimpleActions extends Actions { 
    private static final Actions STAND = ...; 

    @Override Actions stand() { return STAND;} 
} 

並調用

t.stand(); 

其中t是提供給T的實例施工時爲A。或者也許可以將此方法轉換爲其他類型(MotionRegistry?),並在構建A時提供該方法的實例。這就是說,你的設計看起來很複雜,我不能動搖你的代碼可以被簡化的感覺(如果兩者都描述相同的動作,你是否需要區分Actions和SimpleActions?)

+0

謝謝!即使我使這些方法是靜態的,它是否也能工作? 是的,我這樣做,因爲我有很多不同的類擴展A,並且每個類都有自己的動作,邏輯上總是相同的,但圖形不同。 –

+0

@Makers_F:不,它不適用於靜態方法。靜態方法的要點是將該方法與特定的類實現聯繫起來。這種方法利用了多態性,它只適用於非靜態方法。 – StriplingWarrior

+0

@StriplingWarrior起初我以爲泛型會幫助我,但我越多使用它們越多,我發現它們很弱..順便說一句,謝謝你的提示!回到爲接縫這麼簡單的事情寫了很多無聊的代碼.. –

3

運行時不知道泛型的類型參數。換句話說,在運行時,A<Actions>A<SimpleActions>之間沒有區別。因此jvm不能說明你想要SimpleActions.STAND,而不是Actions.STAND。如果您需要在運行時知道類型參數,則需要在單獨的變量中執行它們。

如果不清楚,請閱讀「運行時間類型擦除」。

編輯下面您的評論 - 如果你只是在做這種邏輯在構造函數中,你可以做的構造看起來像

A(Class<? extends Action> actionType){ 
    if(SimpleActions.class.isAssignableFrom(actionType)){ 
     doSomething(SimpleActions.STAND); 
    } 
    else{ 
     doSomething(Actions.STAND); 
    } 
} 

如果您需要構造之外同樣的邏輯,然後在A內部創建類型Class<? extends Action>的成員變量以存儲actionType

+0

是的,我讀過它。但是,我怎樣才能把它在一個單獨的變量? 你能告訴我一些(僞)代碼嗎? –

+0

這個接縫很多,除此之外我還會使用很多的炬實現,所以它會變成牆壁的其他的 –

相關問題