【问题标题】:Subclass issue (JAVA)子类问题(JAVA)
【发布时间】:2016-02-19 00:11:08
【问题描述】:

我有一个类 Appointment 有字段:

  • int day
  • int month
  • int year
  • String desc

这会存储约会的描述以及日期。

超级班Appointment

public class Appointment {
    int dayNum;
    int monthNum;
    int yearNum;
    String desc;

    public Appointment(String des, int day) {
        //Monthly Appointments (Check day)
        desc = des;
        dayNum = day;
    }
    public Appointment(String des, int day, int month){
        //Yearly Appointments (Check day AND month)   
        desc = des;
        dayNum = day;
        monthNum = month;
    }
    public Appointment(String des, int day, int month, int year){
        //One Time (Check All)
        desc = des;
        dayNum = day;
        monthNum = month;
        yearNum = year;
    }     
}

这是我的 3 个子类:

一次性约会:Onetime

public class OneTime extends Appointment{
    public OneTime(String des, int day, int month, int year){
        super(des, day, month, year);
    }
    public String getDesc(){
        return desc;
    }
}

每月一次约会:Monthly

public class Monthly extends Appointment{
    public Monthly(String des, int monum){
        super(des, monum);
    }
    public String getDesc(){
        return desc;
    }
}

每年一次约会 Yearly

public class Yearly extends Appointment{
    public Yearly(String des, int day, int month){
        super(des, day, month);
    }
    public String getDesc(){
        return desc;
    }
}

问题: 我被要求将一些不同的Appointment 对象添加到ArrayList(我知道)。但是,我必须编写一个方法occursOn(int day, int month, int year) 来返回当天的所有约会。我不确定的部分是编写occursOn() 方法。假设我有一个 11/22/2018 的约会,我如何将 Monthly 对象与 day 参数/Yearly 与月和日参数/OneTime 与所有参数进行比较?

教科书问题: " 实现超类 Appointment 和子类 OnetimeDailyMonthly。约会有描述(例如,“看牙医”)和一个日期。写一个方法occursOn(int year, int month, int day)来检查约会是否发生在那个日期。例如,对于每月约会,你必须检查当月的日期是否匹配。然后用一个Appointment对象的数组填充一个约会的混合。让用户输入一个日期并打印出该日期发生的所有约会。"

注意:这不是我的作业。我只是在 2 小时内对此进行了单元测试,然后卡住了。

【问题讨论】:

  • 这是一些奇怪的缩进
  • 对不起。粘贴问题。之前应该有修复。
  • Monthly 可能想知道月份中的哪一天。
  • 您也应该有约会限制。只要它们处于活动状态,OneTime 应该匹配 day month year,Yearly 应该匹配 day month,Monthly 应该只匹配 day。如果您觉得自己做的限制比较过多(验证每月/每年的约会是否有效,您可以创建多个 OneTime 约会并将它们包含在父类中)。
  • 我正在考虑将方法occurrenceOn() 添加到所有子类,然后在包含嵌套if 语句的Appointment 类中编写另一个occurrenceOn() 方法。我只是觉得这种方式不是很健壮。

标签: java


【解决方案1】:

首先,你可能想声明Appointment abstract,这样子类必须实现一些方法:

 public abstract class Appointment {

        int dayNum;
        int monthNum;
        int yearNum;
        String desc;

        public Appointment(String des, int day){desc = des; dayNum = day;} //Monthly Appointments (Check day)
        public Appointment(String des, int day, int month){desc = des; dayNum = day; monthNum = month;} //Yearly Appointments (Check day AND month)   
        public Appointment(String des, int day, int month, int year){desc = des; dayNum = day; monthNum = month; yearNum = year;} //One Time (Check All)    

        abstract boolean occursOn(int day, int month, int year);

        abstract String getDesc();

        }

那么,occursOn 在你的类中的实现可能是:

每月

    boolean occursOn(int day, int month, int year){

                return (this.day == day);
}

每年

    boolean occursOn(int day, int month, int year){

        return (this.day == day) && (this.month == month);
}

一次性

    boolean occursOn(int day, int month, int year){

                return (this.day == day) && (this.month == month) && (this.year == year);
}

最后,假设appointments 是一个List,你填充了子类的各种实例,有一个通用方法(可能在你的主类中),它将返回所有对应Appointment 对象的列表:

public List<Appointment> occursOn(int year, int month, int day){

List<Appointment> result = new ArrayList<Appointment>();

  for(Appointment appointment : appointments){

    if(appointment.occursOn(year, month, day))
      result.add(appointment);
  }

return result;

}

【讨论】:

  • 我唯一要改变的是 Daily = Yearly 但这是 OP 想要的答案。我只是写了一个很短的版本,没有为他编码。
  • @pompanoSlayer :谢谢我纠正了这个。 “用户输入日期”部分还有一些工作需要由 OP 来实施。 :)
【解决方案2】:

OccursOn()

应该是超类(Appointment)中的一个抽象方法。 您的每个子类都必须相应地实现它。

一次性 - 检查日、月和年。

每月 - 仅检查日期。

每年 - 检查日期和月份。

【讨论】:

    【解决方案3】:

    一种方法是使用带有可选值的“日期”键的地图,例如像这样:

    class DateKey {
      int day; //always needed
      Integer month; //null in case of monthlies
      Integer year; //null in case of monthlies and yearlies
    
      //override equals() and hashCode()
    }
    

    对地图使用日期键:

    //handling this would be easier with Google Guava's Multimap, if you may use it
    Map<DateKey, List<Appointment>> appointments = ...;
    

    然后您使用 3 步查找:

    List<Appointment> onetimes = appointments.get(new DateKey( day, month, year) );
    List<Appointment> yearlies= appointments.get(new DateKey( day, month, null) );
    List<Appointment> monthlies = appointments.get(new DateKey( day, null, null) );
    

    最后合并 3 个列表。

    最后,DateKey 也可以是Appointment 类的一部分,这将使映射更加一致。我可能会使用一个稍微不同的名称(想想一个),因为它不再只是一个地图键。

    【讨论】:

      【解决方案4】:

      您可以向您的 Appointment 类添加一个方法,以确定 Appointment 是否在这样的给定日期开启。

      public class Appointment {
      
          int dayNum;
          int monthNum;
          int yearNum;
          String desc;
      
          public Appointment(String des, int day){desc = des; dayNum = day;} //Monthly Appointments (Check day)
          public Appointment(String des, int day, int month){desc = des; dayNum = day; monthNum = month;} //Yearly Appointments (Check day AND month)
          public Appointment(String des, int day, int month, int year){desc = des; dayNum = day; monthNum = month; yearNum = year;} //One Time (Check All)
      
          boolean occuresOn(int day, int month, int year){
              if( (this.dayNum == day) && (this.monthNum == month) && (this.yearNum == year))
                  return true;
      
              return false;
      
          }
      }
      

      并在子类中覆盖此功能。

      public class Monthly extends Appointment{
      
          public Monthly(String des, int monum){
              super(des, monum);
          }
          public String getDesc(){
              return desc;
          }
      
          boolean occuresOn(int day, int month, int year){
              if( (this.dayNum == day) )
                  return true;
      
              return false;
      
          }
      }
      
      public class Yearly extends Appointment{
      
          public Yearly(String des, int day, int month){
              super(des, day, month);
          }
          public String getDesc(){
              return desc;
          }
      
          boolean occuresOn(int day, int month, int year){
              if( (this.dayNum == day) && (this.monthNum == month))
                  return true;
      
              return false;
      
          }
      }
      

      现在您可以遍历您的约会并找到约会中的约会:

      List<Appointment> aps = new ArrayList<>(); //initialize this
          for (Appointment ap : aps){
              if(ap.occuresOn(2, 3, 2016))
                  ....
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-23
        • 2014-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        • 2021-03-04
        • 2021-11-12
        相关资源
        最近更新 更多