Java 为实现同一接口的两个子类定义泛型方法
我正在用Java构建一个“联系人管理器” 我有一个名为“Contact的超类,它有两个基类;PersonalContact和BusinessContact 我有一个名为Event的接口,它由类生日和会议实现(生日包含一个DateTime对象,而会议有两个开始和结束时间对象) 个人联系人举行一组生日和业务联系人举行一组会议。 现在,在超类Contact中,我想创建一个名为“getEventsWithinPeriod()”的抽象方法,它将返回给定时间跨度内所有生日和/或会议的树集 问题是,我不知道如何告诉抽象方法,然后告诉基类方法返回什么 例如,这是我在联系人中使用的代码Java 为实现同一接口的两个子类定义泛型方法,java,generics,set,Java,Generics,Set,我正在用Java构建一个“联系人管理器” 我有一个名为“Contact的超类,它有两个基类;PersonalContact和BusinessContact 我有一个名为Event的接口,它由类生日和会议实现(生日包含一个DateTime对象,而会议有两个开始和结束时间对象) 个人联系人举行一组生日和业务联系人举行一组会议。 现在,在超类Contact中,我想创建一个名为“getEventsWithinPeriod()”的抽象方法,它将返回给定时间跨度内所有生日和/或会议的树集 问题是,我不知道如
公共抽象集getEventsWithinPeriod(日期时间开始,日期时间结束);
并亲自接触,
public Set<Birthday> getEventsWithinPeriod(DateTime start, DateTime end){
Set<Birthday> birthdaysThatAreWithin = new TreeSet<Birthday>();
//CODE
return birthdaysThatAreWithin;
public Set getEventsWithinPeriod(日期时间开始,日期时间结束){
设置birthdaysThatAreWithin=newtreeset();
//代码
返回内的生日;
然而,在编译器中,我在Set
上得到了一个错误,即:
返回类型与联系人不兼容。getEventsWithinPeriod(DateTime,DateTime)
我应该使用什么合适的术语和回报?为什么我当前的尝试是错误的
你需要使用
公共抽象类联系人{
公共摘要集getEventsWithinPeriod(日期开始、日期结束);
}
公共类生日扩展联系人实现事件{
@凌驾
公共设置getEventsWithinPeriod(日期开始、日期结束){
返回null;
}
}
重写任何方法时,方法签名应保持不变,签名应保持不变并返回PersonalContact类中的Set使用泛型时,不希望显式指定类型。可以绑定类型,但不希望显式
将您的联系方式更改为
public abstract Set<T extends Event> getEventsWithinPeriod(DateTime start, DateTime end);
这应该能满足您的需求。您有3种解决方案
解决方案1
首先,可以将类设置为泛型,如下所示:
public abstract class Contact<E extends Event> {
// ...
public abstract Set<E> getEventsWithinPeriod(DateTime start, DateTime end);
}
以及更改方法签名:
public Set<Event> getEventsWithinPeriod(DateTime start, DateTime end) {
并且不更改任何其他内容。这与解决方案2的问题相同,如果不强制转换事件,您将无法将事件用作生日
实例
编辑:第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
}
如果您有另一个Contact
实现,其中包含Birthday
事件,则可以将它们传递给processbirthdays方法,而无需进行任何更改
但是,如果您只需要事件,而不关心调用您的联系人的代码中的类型。getEventsWithinPeriod
,那么解决方案2和3肯定是您的最佳选择。如果是这种情况,我个人只会使用解决方案2。为什么您不想继续使用事件
界面f接口,通过定义实现的可见方法列表使代码清晰。只需使用TreeSet
我完全同意@Fess--“getEvents。。。“返回事件,不是吗?在这种情况下,泛型的使用令人困惑且毫无帮助。是的,你们是对的,我最终就是这样做的。我不清楚如何使用接口将两个类合并为“事件”标题下的同一类型”。谢谢你的帮助!我不知道
是否是一个好的做法。因为t
应该是一切,它就像默认界面一样。可能是Contact
,但这意味着在使用Contact的所有其他类和方法中(例如,在我的ContactManager类中,它包含一个Contacts树集),我必须将其更改为Contact?因此我将使用TreeSet???@Imray您可以使用TreeSetThanks,我认为解决方案2将非常好。但是,我的问题是,实际上有什么缺点?这意味着我将无法将事件用作生日实例?我会失去什么?我不需要将Contact类更改为Contact吗?
public class PersonalContact extends Contact<Birthday> {
public Set<Birthday> getEventsWithinPeriod(DateTime start, DateTime end) { ... }
}
Set<Event> birthdaysThatAreWithin = new TreeSet<Event>();
public Set<Event> getEventsWithinPeriod(DateTime start, DateTime end) {
public Set<? extends Event> getEventsWithinPeriod(DateTime start, DateTime end)
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
}
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
}
}