2013-02-20 92 views
0

如果有人能爲我解決這個難題。我相信我錯過了一些東西!Java通用轉換不如預期

interface a { } 
class b implements a { } 
class c extends ArrayList<b> { } 
class d { 
    d(ArrayList<a> param) {} 
} 

class e { 
    public static void main(String[] arg) { 
     d newd = new d(new c()); 
    } 
} 

此代碼有一個錯誤: 錯誤d(ArrayList<a>) is not applicable (actual argument c cannot be converted to ArrayList<a> by method invocation conversion)

當然類c可以轉換爲ArrayList<a>作爲c延伸ArrayList<b>b實現a! 我試過顯式轉換,但沒有幫助。

它沒有意義要麼改變class c extends ArrayList<b>extends ArrayList<a>c的目的是的b集合和接口a只是用於顯示目的。另外類d是一個通用顯示類,它依賴於接口a中表示的功能,因此無法改變這一點。

建議會很方便!

+1

你應該爲你的類使用大寫字母的名字,這樣看起來更難。 – 2013-02-20 15:46:05

+0

喜歡繼承的組合(Effective Java 2 item 16)。 – nattyddubbs 2013-02-20 16:32:57

回答

3

這應該滿足您的需求:

class d { 
    d(ArrayList<? extends a> param) { 
    } 
} 

c不是ArrayList<a>但由於bArrayList<? extends a>a一個亞型。

0

問題是ArrayList與ArrayList不同,即使b擴展A.如果D調用param.add(new AImpl()),其中AImpl是接口A的一些其他實現會發生什麼?

有關更多詳細信息,請參閱The Java Generics Tutorial section on inheritance

(順便說一句,這也是通常不是一個好主意,延長一個ArrayList - 大多數時候,你想成爲包裝它,而不是擴展它。)

0

它應該是:

d(ArrayList<? extends a> param) {} 

ArrayList不是ArrayList的子類,因爲前者可以將a添加到它,而後者不能。

0

請尊重Java命名約定:

interface A { 
} 

class B implements A { 
} 

class C extends ArrayList<B> { 
} 

class D { 

    D(ArrayList<A> param) { 
    } 
} 

class E { 

    public static void main(String[] arg) { 
     D newd = new D(new C()); 
    } 
} 

所以你的假設是:ArrayList<B>是可澆注到ArrayList<A>B implements A。這不是真的,這不是泛型的工作原理。你根本無法投射泛型類型。 嘗試做類似:

final ArrayList<Object> myNewArrayList = new ArrayList<String>(); 

提取問題。
您需要使用bounded type parameters來解決這個問題。改變你的D類:

class D { 

    D(ArrayList<? extends A> param) {   
    } 
} 

會使它作爲現在的工作你說:我想要的任何類型的集合,只要它是一個A