4

我創建覆蓋其擦除爲2個實現的接口之間是相同的方法簽名類的類,但在通用型的問候(微小的差別一個是一種方法推斷的類型,另一種是推斷類的類型)。我正在尋找一個完美的解決方案。我只能編輯繼承的類,而不是原始的傳統接口。名稱衝突,超越失敗,在實現兩個接口與同一消失

要顯示的情況下,我做了一個抽象的來樣,來理解這個問題:

我得到了開發傳統的父類:

public class Developer<C>{ 
    Rate<C> getRate(Taxes<C> tax){ /*...*/ }  
} 

我也得到了一個可出租的傳統接口,與幾乎相同的簽名

public interface Rentable { 
    <C> Rate<C> getRate(Taxes<C> taxes); 
} 

作爲開發商是不可出租,在我的模型,我創建一個特殊的 開發商這既是一個開發者,和可出租材料。

public class OutsourcableDeveloper<C> 
       extends Developer<C> 
       implements Rentable{ 
    @Override 
    public Rate<C> getRate(Taxes<C> taxes){ /*...*/} 
} 

,然後我得到了臭名昭著的

名稱衝突:該方法的getRate(Developer.Taxes)類型的 OutsourcableDeveloper有型可出租的同一消失的 的getRate(Developer.Taxes),但所以OutsourcableDeveloper.getRate()隱藏 開發人員和可出租不覆蓋它

我怎樣才能擺脫它。的getRate()?

這似乎有點不合邏輯失敗的共同覆蓋,但不允許再擴大這兩個標記爲擦除是相等的。

它真的很重要,以至於超類型的一個推斷,從德法類型,並從特別是當我不打算叫何超在我的實現類中的其他事實?鑑於這種簡化,解決這個問題有沒有可能是一個竅門?

編輯:我開了一個更抽象的,少的解決方案爲導向,以我的實際問題,問題討論的繼承設計問題,我相信這是我遇到的實際問題的相關精髓:Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"?

EDIT2 :前面的問題導致我在這裏發佈

回答

0

好的,我找到了解決的辦法。這是clumpsy,但它是比較容易的,如果結構不是很複雜,由我Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"?自己的答案啓發:

public class OutsourcableDeveloper<C> 
       extends Developer<C> 
       implements Rentable{ 

    /* This might not be needed if we don't need to extract C from taxes parameter */ 
    final Class<C> currencyClass; 
    public OutsourcableDeveloper(Class<C> currencyClass){ this.currencyClass = currencyClass;} 

    @Override 
    public Rate<C> getRate(@SuppressWarnings("rawtypes") Taxes taxes){ 
     try{ 
      C taxesCurrency = (C) currencyClass.cast(taxes.getCurrency()); //IF actually needed getting the typed instance 
      return new Rate<C>(taxesCurrency); //Or whatever processing 
     } catch (ClassCastException e){ 
      throw new UnsupportedOperationException("OutsourcableDeveloper does not accept taxes in a currency that its not hims"); 
     } 
    } 
} 

也可能沒有泛型類型爲「擴展開發者」玩,所以它是implictly生的。但我們也對非衝突方法也打字打字

2

答案那麼,他們實際上是不相等的。因爲任何可租用實例都允許給出任何類型參數T,而OutsourcableDeveloper限制它。

當然,你可以認爲你的情況很容易使用的界面

<C> Rate<C> getRate(Taxes<C> taxes); 

版本。但是,如果他想要繼承OutsourceableDeveloper的子類,那麼預計開發人員可能會感到困惑。從開發者的定義,他可以假設法的getRate固定爲C,但實際上它可能突然採取任何價值。 - >這會導致混淆。

我能爲您提供的是以下代碼示例,它可能適合您的情況。儘管使用它肯定會很不方便。但是當你將所有方法轉發到OursourcableDeveloperRentable時,這是可能的。評論應該解釋它是如何工作的。

//This class itself can be added to any Developer-lists 
public class OutsourcableDeveloper<C> extends Developer<C> { 

    public final OutSourcableDeveloperRentable RENTABLE_INSTANCE = new OutSourcableDeveloperRentable(); 

    @Override 
    public Rate<C> getRate(final Taxes<C> taxes) { 
     // Simply forward to the more general getRate instance. 
     return this.RENTABLE_INSTANCE.getRate(taxes); 
    } 

    public void exampleBehaviourA() { 
     //Example for how you can make both objects behave equally. 
    } 

    // This class can be added to the lists requiring a Rentable 
    // And the original value can be retrieved by both classes. 
    public class OutSourcableDeveloperRentable implements Rentable { 

     public final OutsourcableDeveloper<C> PARENT_INSTANCE = OutsourcableDeveloper.this; 

     //This method is the one to implement because it is more general than 
     //the version of OutsourcableDeveloper. 
     @Override 
     public <T> Rate<T> getRate(final Taxes<T> taxes) { 
      // Do your work. 
      return null; 
     } 

     public void exampleBehaviourA() { 
      //Just an example - Maybe for you it makes for sence to 
      //forward the method of Oursoursable-Developer to here. 
      //Then all Behaviour would be found in this class. 
      OutsourcableDeveloper.this.exampleBehaviourA(); 
     } 

    } 
} 
+0

很好的答案謝謝(我會等待看看是否有任何棘手或簡單的問題)!順便說一句,如果我不能選擇方法在我的孩子的方法限制版本,名稱衝突:類型OutsourcableDeveloper 類型的getRate(Developer.Taxes )具有與getRate(Developer.Taxes )類型相同的擦除開發者但不覆蓋它 – Whimusical

+0

在我看來,這些行爲沒有理由,編譯器應該強制執行更嚴格的兩個。我實現了同樣的方法,在一個接口中,類型是*,在另一個接口中必須與類相同,所以如果你實現了這兩個接口,受限制的類可以透明地暴露出來,而不會破壞我相信的任何不連貫性。 – Whimusical

+0

這是不可能的。接口的調用者期望允許任何參數。如果你通過編程限制他們,你會破壞OOP意圖。 –

相關問題