2014-03-24 40 views
1

跟進this question,但我會盡量讓它自成一體。如何使擴展接口與通用參數兼容?

假設我有一個名爲Animal的接口,這對於各種原因具有代表實現類泛型類型參數:

public interface Animal<A extends Animal<A>> 

我也有一個子接口,Dinosaur,其行爲以同樣的方式:

public interface Dinosaur<D extends Dinosaur<D>> extends Animal<D> 

現在我有一個類Lizard它實現Animal

public class Lizard implements Animal<Lizard> 

和一個子類,Trex,它實現Dinosaur

public class Trex extends Lizard implements Dinosaur<Trex> 

這四個聲明現在產生錯誤。這是因爲類Trex實現了兩次接口Animal,但具有不同的類型參數:由於它擴展了Lizard,它實現了接口Animal<Lizard>,並且由於它實現了Dinosaur<Trex>,它實現了Animal<Trex>

Animal<Trex>不是Animal<Lizard>子接口,即使TrexLizard一個子類,所以我們得到一個編譯錯誤。

我敢肯定,有一些解決方法使用通配符,但我無法弄清楚它是什麼。

這裏的東西,你可以編譯得到了同樣的錯誤:

public class InterfaceTest 
{ 
    private interface Animal<A extends Animal<A>> {} 

    private interface Dinosaur<D extends Dinosaur<D>> extends Animal<D> {} 

    private class Lizard implements Animal<Lizard> {} 

    private class Trex extends Lizard implements Dinosaur<Trex> {} 
} 

回答

2

This is because the class Trex implements the interface Animal twice, but with different type parameters

是啊,這樣的話,這裏面的這個直接周圍也沒有路 - 這是一個技術上的限制,因爲仿製藥使用擦除實現。 永遠不能在具有不同通用參數的多個類上實現相同的接口。當通用類型被刪除時,最終會以相同的方式擴展兩個接口,無法區分使用這些不同通用類型的方法,因此運行時無法確定要執行哪種方法。

對於您的特定用例,可能有一種解決方法,這意味着您不必使用不同的類型參數實現相同的接口,但沒有更多細節,不可能說出可能的內容。

編輯:看看鏈接的問題,它看起來像你可以解決這個問題,通過使用其他答案(你還沒有接受),以這種方式指定返回值,而不是在類上聲明:

public <T extends JNumber> T add(T addend); 

這應該那麼意味着你不需要聲明你的類和接口的泛型類型參數,然後因此不應該有這個問題。

+1

是的 - 使用其他答案正是我想到的解決方法。非常感謝您的幫助。 –

+0

@ Donkey_2009沒問題。 – berry120