您有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