2013-02-06 19 views
0

做一些閱讀後,看來,它是可以使用&操作需要多個擴展:Class<T extends Class1 & Class2> classObj;的Java:不是運營商通配符限制

不過,我正在尋找一種方式來執行「不」功能在編譯時。我有香蕉延長水果的例子。不過,我沿着線的東西后我:

public abstract class Fruit 
{ 
    public abstract String getFlavour(); 
} 

public class Lemon extends Fruit 
{ 
    @Override 
    public String getFlavour() 
    { 
     return "sour"; 
    } 
} 

public abstract class Banana extends Fruit 
{ 
    @Override 
    public String getFlavour() 
    { 
     return "very sweet!"; 
    } 

    public abstract String getBananaRipeness(); 
} 

public class UnripeBanana extends Banana 
{ 
    @Override 
    public String getBananaRipeness() 
    { 
     return "unripe"; 
    } 
} 

... 
    public String methodThatTakesFruitClassButNotBanana(Class<? extends Fruit ! Banana> fruitClass) 
    { 
     Fruit fruit = fruitClass.newInstance(); 
     return fruit.getFlavour(); 
    } 

... 
     methodThatTakesFruitClassButNotBanana(Lemon.class); // I want this to compile. 
     methodThatTakesFruitClassButNotBanana(UnripeBanana.class); // I want this not to compile. 

顯然Class<? extends Fruit ! Banana>無效語法。你會推薦什麼方法來在編譯時強制執行這種類型的層次結構?

+5

我不認爲有一個簡單的方法來做到這一點 - 更容易的是在運行時拋出異常。但在嘗試尋找解決方法之前,我會質疑設計。如果你可以用一種不能用香蕉完成的水果做某些事情,那麼無論你的香蕉是不是一種水果或更可能,你已經把太多東西放在水果中,而這些東西不適用於任何水果。 – assylias

+0

@assylias - >你擊中了頭部。香蕉確實是一種水果,但是在我們的設計中,它好像是延長了另一種水果 - 它應該已經在層次結構中的更高層而不是它在哪裏。 – studro

回答

4

公共字符串methodThatTakesFruitClassButNotBanana

這是里氏替換原則的完全相反,如何多態性的作品。由於Banana extends Fruit有任何需要Fruit接受Banana的任何方法的要求。

如果你有,你需要檢查動態類型並拋出異常,編譯器不能爲你做這件事。

+0

我完全同意。我們有一個單元測試框架,採取香蕉(除其他事情以外的水果),我需要擴展它與檸檬,橙子,蘋果等工作。在這個框架中的香蕉處理不同於其他水果。設計的問題是內在的問題,實際上它更像香蕉延伸檸檬。香蕉在層次結構中的位置太低。但是,這不是我可以改變的東西,所以我將不得不面對艱難的(運行時)失敗。非常感謝。 :) – studro