2013-07-31 66 views
2

我對Java相當新,並沒有使用接口,這是我想象的是一個非常基本的問題。Java方法不適用於參數(接口)

我定義它實現了第二連接器的接口,其延伸它的第二接口,然後一類:

public interface I1 { 
    public void doStuff(); 
} 

public interface I2 extends I1 { 
    public void doMoreStuff(); 
} 

public class C2 implements I2 { 
    public void doStuff(){ 
    // implements I1 as required 
    } 
    public void doMoreStuff(){ 
    // implements I1 as required 
    } 
} 

我然後想要調用具有作爲參數的對象的集合的方法,其實現接口I1:

public class C3 { 
    public static void doI1Stuff(List<I1> implementorsOfI1){ 
     // code here 
    } 
} 

,但我得到了上述錯誤,當我嘗試像

C2 aC2 = new C2(); 
List c2L = new List<I2>(); 
c2L.add(aC2); 
C3.doI1Stuff(c2L); 

我所做的事情對我而言似乎是合理的java新手。爲什麼它不起作用,更有經驗的程序員會做什麼?我希望我已經在某個地方犯了一個非常簡單的錯誤,這實際上是可能的...

(修改後的問題:如果我正在處理單個C2對象,但它與它們的集合無關...)

+3

這應該很好。你得到的確切的編譯器錯誤是什麼?確保你沒有做一些奇怪的事情,比如導入一個具有相同名稱的不同類 - 這在試驗時經常是一個問題。 –

+0

你的例子對我來說看起來很好。 –

+0

適合我。 – ikdc

回答

1

UPDATE

哎呀,你C2L是List,而不是一個List`。這應該編譯 - 它的確如同評論的其他人一樣 - 雖然由於我在下面描述的相同原因,它是危險的。我將在這裏離開這個答案現在,但我可以刪除它,如果我發現它是沒有用的


public static void doI1Stuff(List<I1> implementorsOfI1) 
... 
C3.doI1Stuff(c2L); 

doI1Stuff需要一個List<I1>但你傳遞一個List<I2>這是不允許的。聽起來很奇怪,「一袋蘋果不是一袋水果」。原因是您可以將任何水果放在一袋水果中,例如,香蕉,但你不能用一袋蘋果做到這一點。

把它與你的例子考慮也有一個class C1 extends I1doI1Stuff可以添加一個C3該paramer,違約。它可能會澄清意識到您的參數命名錯誤,它應該是listOfImplementorsOfT1

一個解決您的問題的方法是申報更改爲

public static void doI1Stuff(List<? extends I1> implementorsOfI1) 

這是說的參數是一些未知類型extends I1列表。 List<I2>,List<C2>List<C1>都滿足約束條件。有了這個聲明,該方法不能向該列表添加任何內容,因爲它不知道該類型是什麼。

+1

我想我明白了。危險在於doI1Stuff可能會嘗試向傳遞給它的集合中添加一些不符合I2的對象,因此在返回調用方時可能會發生不好的事情。 – PGB

+0

你明白了:)但看到我的更新,你的例子是在一些必要的改變之後編譯的。也許你可以逐字地發佈代碼? –

相關問題