2010-10-14 148 views
4

有了這個設計:Java的泛型和接口

interface Foo<T> { 
    void doSomething(T t); 
} 

class FooImpl implements Foo<Integer> { 
    //code... 
} 

interface Bar extends Foo { 
    //code... 
} 

class BarImpl extends FooImpl implements Bar { 
    //code... 
} 

它給了我編譯錯誤:

接口美孚不能 實施不止一次與 不同的參數:Foo和 富

一個簡單的修復這個問題是:

interface Bar extends Foo<Integer> { 
// code... 
} 

Bar接口中的整數型是完全沒用的。

有沒有更好的方法來解決這個問題? 有什麼更好的設計?

感謝您的建議。

編輯:

給出解決方案:

> interface Bar<T> extends Foo<T> 

是好的,但它作爲我以前的解決方案相同。我不需要T型酒吧。

讓我給一個更好的例子:

interface ReadOnlyEntity { 
} 

interface ReadWriteEntity extends ReadOnlyEntity { 
} 

interface ReadOnlyDAO<T extends ReadOnlyEntity> { 
} 

interface ReadWriteDAO<K extends ReadWriteEntity, T extends ReadonlyEntity> extends ReadOnlyDAO<T> { 
} 

這是一個好的設計?

+1

這個問題不能沒有你實際的接口名稱來回答。 – SLaks 2010-10-14 12:39:55

+0

這是因爲泛型是Java(擦除)中的編譯時魔術,因此不能使用不同的泛型參數兩次實現相同的接口。 – Lucero 2010-10-14 12:56:55

+0

@SLaks:請看看編輯部分。 – mhshams 2010-10-14 14:05:49

回答

5

我建議您考慮Bar通用類型或重新考慮您的設計。如果沒有對Bar有意義的對象,那麼它不應該實現Foo<T>

編輯:

這是一個好的設計?

不,在我看來。

+0

+1我正要發帖一樣,直到我看到你的回答 – 2010-10-14 12:51:47

+0

請看編輯部分 – mhshams 2010-10-14 13:43:28

3
interface Bar<T> extends Foo<T> { 
    // code... 
} 

class BarImpl extends FooImpl implements Bar<Integer> { 
    // code... 
} 

但是,如果我們知道接口的確切語義,最好。

+0

請看看編輯過的部分 – mhshams 2010-10-14 13:44:26

2

主要問題是你有兩個不同的泛型使用相同的接口;一個用Integer,另一個用默認的Object

唯一的解決辦法是有確切的相同的通用Integer

您可以通過直接指定interface Bar extends Foo<Integer>來實現,但如果BarFoo<Integer>沒有特別關係,則無意義。

另一種方法是泛型化Bar並使用此通用於延伸Foo

interface Bar<T> extends Foo<T>{ 
    //... 
} 

無論哪種方式,如Bar涉及Foo;所以要麼在Bar(硬編碼)中指定Foo的類型,要麼必須具有通用的Bar

0
interface Bar<T> extends Foo<T> { 
// code … 
} 

這是你在找什麼?一個通用酒吧?

「更好的方式」是一種模糊。

0

「在酒吧接口整型是 完全無用。」

將表明,酒吧其實並沒有延長符如果通用類型是相關的在那裏。 更合適的是Foo和Bar都可以擴展的基本接口。

0

Bar界面中的整數型是 完全沒用。

我不需要酒吧的T型。

這表明您的設計出了問題,沒有必要用Bar來擴展Foo。順便說一下,完美適合這裏是多繼承,但Java不支持它。

按照你的榜樣,應該更有意義如下:

interface ReadOnlyEntity<T> { 
/* do something with generics */ 
T read(); 
} 

interface WriteOnlyEntity { 
/* do something without generics */ 
void write(); 
} 

class abstract BaseReadWriteEntity<T> implements ReadOnlyEntity<T>, WriteOnlyEntity { 
} 

interface ReadOnlyDAO<T extends ReadOnlyEntity> { 
} 

interface ReadWriteDAO<T extends BaseReadWriteEntity> extends ReadOnlyDAO<T> { 
}