您有3個解決方案。
解決方案1
首先,你可以讓你的類通用的,就像這樣:
public abstract class Contact<E extends Event> {
// ...
public abstract Set<E> getEventsWithinPeriod(DateTime start, DateTime end);
}
,然後在具體落實:
public class PersonalContact extends Contact<Birthday> {
public Set<Birthday> getEventsWithinPeriod(DateTime start, DateTime end) { ... }
}
這是最好的解決辦法,但你有一些選擇。
解決方案2
你可以改變你birthdaysThatAreWithin
字段的類型:
Set<Event> birthdaysThatAreWithin = new TreeSet<Event>();
以及改變方法的簽名:
public Set<Event> getEventsWithinPeriod(DateTime start, DateTime end) {
,並返回它這樣。這限制了您,因爲您不能再使用Birthday
實例的事件。
解決方案3
你也可以改變你的方法簽名(在你的抽象和具體類兩者)這樣的:
public Set<? extends Event> getEventsWithinPeriod(DateTime start, DateTime end)
,並沒有改變任何東西。這有與解決方案2相同的問題,您將無法使用事件作爲Birthday
實例而不投射它們。
編輯:缺點2和3是他們將需要鑄造。例如:
PersonalContact contact = ... ;
Set<Event> events = personalContact.getEventsWithinPeriod(start, end);
// I know all the events are birthdays, but I still have to do this:
for (Event event : events) {
if (event instanceof Birthday) {
Birthday birthday = (Birthday) event;
// Do stuff with birthday
} // else maybe log some error or something
}
有了第一個解決方案,你有這樣的:
PersonalContact contact = ... ;
Set<Birthday> birthdays = personalContact.getEventsWithinPeriod(start, end);
for (Birthday birthday : birthdays) {
// Do stuff with birthday
}
代碼看起來更清潔,運行更好,因爲你沒有做instanceof
檢查,以確保你不沒有得到ClassCastException
。您也可以有這樣的東西:
public static void processBirthdaysFor(Contact<Birthday> birthdayContact, DateTime start, DateTime end) {
Set<Birthday> birthdays = personalContact.getEventsWithinPeriod(start, end);
for (Birthday birthday : birthdays) {
// Do stuff with birthday
}
}
如果你曾經有Contact
有Birthday
事件另一種實現方式,可以將它們傳遞給processBirthdaysFor
方法,無需進行任何更改。
然而,如果你只需要事件和你不在乎什麼類型的代碼中調用你的Contact.getEventsWithinPeriod
,然後解決方案2和3是絕對你最好的賭注。如果是這種情況,我個人只會使用解決方案2。
爲什麼你不想繼續使用'Event'接口?接口的主要思想是通過定義實現的可見方法列表來使代碼清晰。只需使用'TreeSet' –
我完全同意@Fess - 這似乎很清楚,「getEvents ...」返回事件,不是嗎?在這種情況下使用泛型只是混淆和無益的。 –
是的,你們是對的,我最終這樣做了。我沒有清楚地瞭解如何使用界面將兩個班級統一爲「Events」標題下的相同類型。謝謝你的幫助! – CodyBugstein