2013-07-20 138 views
0

的Java防止調用所以我有自定義類,看起來像這樣:泛型方法

public class Cell { 
    protected boolean wasActive; 

    public Cell() { 
    this.wasActive = false; 
    } 

    public boolean getPreviousActiveState() { 
    return this.wasActive; 
    } 

    public void setPreviousActiveState(boolean previousActiveState) { 
    this.wasActive = previousActiveState; 
    } 
} 

現在我在這裏寫另一個類我需要調用上述getPreviousActiveState()方法:

public class Synapse<Cell> { 
    private Cell cell; 

    // some other methods... like isConnected 

    public boolean getPreviousActiveState() { 
    this.cell.getPreviousActiveState; // <= CAN'T BE CALLED. WHY? 

    } 
} 

我知道這個問題已經做的事實,我聲明的類:

public class Synapse<Cell> 

,但我沒有THI所以只有Synapse只能包含Cell的一個子類。例如,我也實現了一個VisionCell,AudioCell和Neuron類,它們都可以擴展Cell。這種泛型使用是否不必要?如果是這樣,我應該什麼時候使用泛型?謝謝!

+3

這不是你如何使用泛型。 – bmargulies

+2

'公共類Synapse '然後使用'T'。 – jlordo

+0

然後讓它成爲一個方法調用... –

回答

3

定義稱爲Cell的類型參數意味着會產生一些混淆。讓我們把它重命名爲T,並且還增加了對失蹤括號向this.cell.getPreviousActiveState電話:

class Synapse<T> { 
    private T cell; 

    // some other methods... like isConnected 

    public boolean getPreviousActiveState() { 
    return this.cell.getPreviousActiveState(); // <= CAN'T BE CALLED. WHY? 
    } 
} 

的錯誤,你現在得到的是: The method getPreviousActiveState() is undefined for the type T

這是告訴你,沒有編譯器的方式在代碼中它保證類型參數T有一個getPreviousActiveState()方法。請注意,Java泛型不像C++模板:泛型類獨立於任何調用站點編譯一次。換句話說,編譯器不檢查這個類的w.r.t到任何特定的實例,而是它檢查它是否有意義。

爲了保證T有一個getPreviousActiveState()所有您需要做的就是指定一個定義此方法的T的上限。我們可以用Cell本身:

class Synapse<T extends Cell> { 
    private T cell; 

    // some other methods... like isConnected 

    public boolean getPreviousActiveState() { 
    return this.cell.getPreviousActiveState(); // <= Compiles! 
    } 
} 

當然,你可以使代碼更通用通過引入定義你感興趣的方法(S)的接口,並使用這個接口作爲上限。您還必須使Cell實現此接口:

interface ActiveStateProvider { 
    public boolean getPreviousActiveState(); 
} 

class Cell implements ActiveStateProvider { 
    protected boolean wasActive; 

    public Cell() { 
    this.wasActive = false; 
    } 

    public boolean getPreviousActiveState() { 
    return this.wasActive; 
    } 

    public void setPreviousActiveState(boolean previousActiveState) { 
    this.wasActive = previousActiveState; 
    } 
} 

class Synapse<T extends ActiveStateProvider> { 
    private T cell; 

    // some other methods... like isConnected 

    public boolean getPreviousActiveState() { 
    return this.cell.getPreviousActiveState(); // <= Compiles! 
    } 
}