2012-09-27 65 views
6

我的問題可能是很簡單的,的Java:對於每一個循環,遍歷所有擴展對象

我有一個類Result一些內場,getter和setter方法。

此外,我有類Special1Result它延伸Result,包括幾個字段和Special2Result與一些更多的數據。

在不同的類Dispatcher,我寫了下面的方法:

processResults(List<? extends Result> results),這是唯一熟悉Result(我需要這個方法來查詢是否有特定的領域擴展結果的對象 - 我使用的註解)。

所以我已經決定使用擴展for-each循環:for (Result res : results) {}

那麼,什麼是我的問題嗎?我試圖通過網絡找到如何爲擴展對象編寫循環,例如像這樣的東西for (? extends Results res: results){}

這可能嗎?如何編寫它的正確方法?

回答

2

我想通過網絡找到如何爲擴展對象編寫循環,例如像這樣

for (? extends Results res: results){} 

不,這是不可能的:你不能靜態類型在運行時動態提供的物品。

如何正確寫入它?

你已經在做了:

for (Results res: results) { 
} 

如果你想測試Special2Result該循環內,你可以做到這一點,但通常它會告訴你的設計可以得到改善。更好的選擇是使用雙派遣機制,例如Visitor Pattern來隱藏您的子類的特殊治療細節。

+1

中的一些功能+1謝謝,我將檢查如何使用訪問者模式這裏。 – Michael

+0

+1爲訪問者模式。 – EthanB

5

關於List<? extends Result>的全部知識就是每個元素都是Result--所有這些都可以放在增強的for循環語法中。

如果需要未在Result聲明成員,則需要投在循環中:

for (Result result : results) { 
    if (result instanceof CleverResult) { 
     CleverResult clever = (CleverResult) result; 
     // Use clever here 
    } 
} 

想想,如果你使用增強的不你會寫什麼for循環 - 你仍然需要寫演員,不是嗎?

當然,如果你知道該列表應該是真的只包含一個特定類型,那麼你總是可以無條件地在循環中投射。

+0

+1,謝謝,雖然我不能問什麼是instanceof的,因爲我不知道不同類型的特殊結果的調度class – Michael

+0

@Michael:那麼你無法明智地使用這種差異,所以沒關係,對吧?爲什麼你會希望有一個你無法預測的變量? –

+0

當您使用遠程團隊進行編程時,經常使用它,只要您使用預定義的格式(例如使用註釋)就可以對框架負責並允許您擴展其對象。我正在使用的產品實現了這一設計,我希望將其擴展一點。使用註釋(@interface),你可以向超類的用戶指出哪些字段是重要的,哪些類型將被檢查等等......框架設計者仍然需要能夠由不同的開發者處理擴展對象而不知道什麼實現。 – Michael

1

Java有類型擦除 - 集合的具體類型參數在運行時不存在。

所以,如果你有一個List,java編譯器將確保沒有代碼將任何東西放入不是Result的子類的列表中。

因此,在運行時,您的所有循環都可以知道內容是Result的所有子類 - 因此循環它們的唯一方法是作爲Result的一組引用,以及任何多態行爲作爲列表中的任何子類的結果。

+0

+1,謝謝,我在過去曾經說過,如果你把一個更大的擴展對象投射到一個更小的超類對象上,你可能會丟失類 – Michael

1

由於您的具體子類只根據字段的性質不同,因此我建議您從簡單的多態性中受益。

您將最終得到一個接口/抽象類,該接口/抽象類定義​​方法類,該類由您需要包含自己的動作來執行的儘可能多的類或子類實現。

因此,您的客戶端代碼可以使用只是:

for (Result res : results){ //results being as a List<Result> type 
    res.execute(); 
} 
+0

+1,謝謝,我會檢查如果執行是一個選項。 – Michael