[英]Java: For each loop , Iteration over extended objects
我的問題可能很簡單,
我有一個帶有一些內部字段,setter和getter的類Result
。
另外,我有一個類Special1Result
,它擴展了Result
並包含了更多的字段和Special2Result
以及更多的數據。
在不同的Dispatcher
類中,我編寫了以下方法:
processResults(List<? extends Result> results)
,它只熟悉Result
(我需要這個方法來查詢擴展Result對象中是否有特定字段 - 我正在使用注釋)。
所以我決定使用擴展for-each循環: for (Result res : results) {}
那么我的問題是什么? 我試圖通過網絡找到如何為擴展對象寫這個for循環,例如這樣的東西for (? extends Results res: results){}
可能嗎? 寫它的正確方法怎么樣?
你對List<? extends Result>
所有了解List<? extends Result>
List<? extends Result>
是每個元素都是一個Result
- 所以你可以放入增強的for循環語法。
如果您需要未在Result
聲明的成員,則需要在循環內部進行強制轉換:
for (Result result : results) {
if (result instanceof CleverResult) {
CleverResult clever = (CleverResult) result;
// Use clever here
}
}
想想如果你沒有使用增強的for循環你會寫什么 - 你還需要寫演員,不是嗎?
當然,如果您知道列表實際上只包含一個特定類型,則始終可以無條件地在循環中進行轉換。
我試圖通過網絡找到如何為擴展對象編寫這個for循環,例如像這樣的東西
for (? extends Results res: results){}
不,這是不可能的:您無法靜態鍵入在運行時動態提供的項目。
寫它的正確方法怎么樣?
你已經這樣做了:
for (Results res: results) {
}
如果您想在該循環中測試Special2Result
,您可以這樣做,但通常它會告訴您的設計可以改進。 更好的選擇是使用雙重調度機制(例如訪問者模式 )來隱藏子類的特殊處理細節。
Java具有類型擦除 - 集合的具體類型參數在運行時不存在。
因此,如果您有一個List,那么java編譯器將確保沒有代碼將任何內容放入不屬於Result子類的列表中。
因此,在運行時,您的所有循環都可以知道內容是Result的所有子類 - 因此循環它們的唯一方法是作為Result的一組引用,具有任何子類的結果所呈現的任何多態行為在列表中。
由於您的具體子類僅因字段的性質而不同,我建議您從簡單的多態性中受益。
您最終將得到一個Result
接口/抽象類,它定義一個execute()
方法類,該類由您需要包含自己要執行的操作的多個類或子類實現。
因此,您的客戶端代碼只能使用:
for (Result res : results){ //results being as a List<Result> type
res.execute();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.