2014-09-29 53 views
1

我有一個接口,並實現它的類:不能通過的ArrayList <Impl>到方法採取的ArrayList <Interface>

public interface IFoo{ 
    Integer bar(); 
} 

public class Foo implements IFoo{ 
    @Override 
    public Integer bar(){ 
     return 42; 
    } 
} 

現在,在另一個類,我有一個函數,該函數的接口類型的ArrayList。

public class Something { 
    public static void function(ArrayList<IFoo> foos){ 
     //do something on foos 
    } 
} 

我想用這個函數foo的數組列表:

ArrayList<Foo> myFoos = new ArrayList<Foo>(); 
Something.function(myFoos);//can NOT do this 

有什麼問題或者我該怎麼辦?

+2

稍微偏離主題,但爲什麼不'公共靜態無效的功能(的IFoo FOOS ...)'? – Leon 2014-09-29 05:42:37

+0

我同意@Leon。編碼到*界面*是一個好習慣。 – TheLostMind 2014-09-29 05:43:41

+0

你的界面名稱是IFoo,而你生成的arraylist是Foo。但是在函數簽名裏面的Something類中你已經提到了正確的。 – 2014-09-29 05:43:49

回答

6

通用救援!

public static void function(ArrayList<? extends IFoo> foos){ 
    //do something on foos 
} 

現在函數採用任何種類的數組列表,其中所包含的類型是IFoo或從它衍生。

對於什麼是值得的,使用最通用的類​​型也是一個好主意。你真的需要一個ArrayList,或者任何一種List嗎?或者,也許任何種類的Collection

public static void function(List<? extends IFoo> foos); 
public static void function(Collection<? extends IFoo> foos); 

一個很好的經驗法則是be conservative in what you send and liberal in what you accept from others。使用更通用的參數類型屬於「自由」部分。

+0

謝謝。集合類型可能取決於。 – 2014-09-29 05:51:21

0

您可以通過使用泛型做到這一點:

public static void function(ArrayList<? extends IFoo> foos){ 

} 

所以你的問題很容易得到解決。

1

我會可能保留方法簽名不變(除了接受List<IFoo>),促進接口類型的使用,如:

List<IFoo> myFoos = new ArrayList<IFoo>(); 

如果需要使用List<Foo> - 再次,與ArrayList! - 那麼我可能會保留更簡單的簽名,並強制主叫方適當地進行投票,或者以其他方式提供表達式,將此類操作的責任留在呼叫地點。

(我主要是偏見子類型,並且更喜歡實用時迴避這個covariance issue完全。)

+0

好吧,我會咬。你爲什麼偏向於分類? – 2014-09-29 06:01:16

+0

@JohnKugelman沒有那麼多的子類型作爲繼承子類型 - 關係:主要是對LSP(超出定義的接口契約)和具體類型的增加(並且太簡單)的依賴性。 – user2864740 2014-09-29 06:12:04

+0

啊,知道了。我在那裏同意你的意見。我認爲你有一些針對通配符限定符的具體內容。這是一個奇怪的具體事情,恨。;-) – 2014-09-29 06:15:25

相關問題