Joe Green
Joe Green

Reputation: 3

Subclass issue (JAVA)

I have a class Appointment with fields:

This stores the description of the appointment along with the date.

Super class 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;
    }     
}

Here are my 3 sub classes:

A one time Appointment: 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;
    }
}

Once a month Appointments: Monthly

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

Once a year Appointments Yearly

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

Problem: I am asked to add a handful of various Appointment objects to an ArrayList (which I know). However, I must write a method occursOn(int day, int month, int year) that returns all appointments on that day. The part I am not sure about is writing the occursOn() method. Say I had an Appointment for 11/22/2018 , how would I compare a Monthly object to the day parameter / Yearly compared to the month and day parameters / OneTime compared to all parameters?

Textbook question: " Implement a superclass Appointment and subclasses Onetime, Daily, and Monthly. An appointment has a description (for example, "see the dentist") and a date. Write a method occursOn(int year, int month, int day) that checks whether the appointment occurs on that date. For example, for a monthly appointment, you must check whether the day of the month matches. Then fill an array of Appointment objects with a mixture of appointments. Have the user enter a date and print out all appointments that occur on that date. "

Note: This is not my homework. I just have a unit test on this in 2 hours and am stuck.

Upvotes: 0

Views: 4413

Answers (4)

Arnaud
Arnaud

Reputation: 17534

First of all, you may want to declare Appointment abstract, so that sublcasses have to implement some methods :

 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();

        }

Then, the implementation of occursOn in your classes could be :

Monthly

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

                return (this.day == day);
}

Yearly

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

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

OneTime

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

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

Finally, assuming that appointments is a List you populated with various instances of the subclasses, have a general method (maybe in your main class), which will return the list of all corresponding Appointment objects :

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;

}

Upvotes: 1

pompanoSlayer
pompanoSlayer

Reputation: 163

OccursOn()

Should be an abstract method in the superclass (Appointment). Each one of your sub class will have to implements it accordingly.

Onetime - check day, month, and year.

Monthly - check day only.

Yearly - check day and month.

Upvotes: 0

ayyoob imani
ayyoob imani

Reputation: 639

You can add a method to your Appointment class that determines if the Appointment is on on a given date like this.

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;

    }
}

And override this functionality in sub classes.

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;

    }
}

now you can iterate over your appointments and find those that are on a date:

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

Upvotes: 0

Thomas
Thomas

Reputation: 88757

One way to go would be a map that uses a "date" key with optional values, e.g. like this:

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()
}

Use the date key for a map:

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

Then you use a 3-step lookup:

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) );

And finally combine the 3 lists.

Finally, the DateKey could also be part of the Appointment class which would make the mapping even more consistent. I'd probably use a slightly different name then (think of one) since it's not only a map key anymore.

Upvotes: 0

Related Questions