Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为实现同一接口的两个子类定义泛型方法_Java_Generics_Set - Fatal编程技术网

Java 为实现同一接口的两个子类定义泛型方法

Java 为实现同一接口的两个子类定义泛型方法,java,generics,set,Java,Generics,Set,我正在用Java构建一个“联系人管理器” 我有一个名为“Contact的超类,它有两个基类;PersonalContact和BusinessContact 我有一个名为Event的接口,它由类生日和会议实现(生日包含一个DateTime对象,而会议有两个开始和结束时间对象) 个人联系人举行一组生日和业务联系人举行一组会议。 现在,在超类Contact中,我想创建一个名为“getEventsWithinPeriod()”的抽象方法,它将返回给定时间跨度内所有生日和/或会议的树集 问题是,我不知道如

我正在用Java构建一个“联系人管理器”

我有一个名为“Contact的超类,它有两个基类;PersonalContactBusinessContact

我有一个名为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
    }
}