public class PolyMorphDemo{ public static void main(String[] args){ Date date = new Date(2006,11,8); System.out.println(date); Date date2 = new Date(2006,12,31); System.out.println(date2); System.out.println(date.weeksLater(date2)); System.out.println("the later date is " + Max.maxObj(date,date2)); } } class Max{ public static Comparable maxObj(Comparable o1, Comparable o2){ if(o1.compareTo(o2)>= 0){ return o1; } return o2; } } class Date implements Comparable{ int year; int month; int day; public Date(){ this((int) (2000*Math.random()) + 1000, (int)(12*Math.random()) + 1, (int)(31*Math.random()) + 1); } public Date(int yr, int mo, int da){ year = yr; month = mo; day = da; } // advance the day by n public void advanceDay(){ if (day < monthLength()) { day = day + 1; } else { day = 1; month++; } } public String toString(){ System.out.println("Date toString called"); return "Year " + year + " Month " + month + " Day " + day; } public int monthLength(){ if (month == 2) return 28; else if (month == 9 || month == 4 || month == 6 || month == 11) return 30; else return 31; } public boolean equals(Object other){ System.out.println("Date equals called"); if (other instanceof Date) { Date otherDate = (Date)other; return (this.year == otherDate.year && this.month == otherDate.month && this.day == otherDate.day); } else{ return false; } } public boolean notEquals(Object other){ return !equals(other); } public int compareTo(Object other){ Date o = (Date) other; if(equals(o)){ return 0; } if(year < o.year||year == o.year & month < o.month|| year==o.year && month == o.month && day < o.day){ return -1; } return 1; } public int weeksLater(Date other){ int days = 0; if(this.compareTo(other) > 0){ Date temp = new Date(other.year, other.month, other.day); while(!this.equals(temp)){ temp.advanceDay(); days++; } return days / 7; } else{ Date temp = new Date(this.year, this.month, this.day); while(!other.equals(temp)){ temp.advanceDay(); days++; } return -days / 7; } } } class Time extends Date{ private int hour; private int minute; private int second; public Time() { super(); hour = (int) (24*Math.random()); minute = (int) (60*Math.random()); second = (int) (60*Math.random()); } public Time(int yr, int mo, int da, int hr, int min, int sec){ super(yr, mo, da); hour = hr; minute = min; second = sec; } public String toString(){ return super.toString() + " Hour " + hour + " Minute " + minute + " Second " + second; } public boolean morning(){ return (hour < 12); } public boolean equals(Object other){ System.out.println("Time equals called"); if (other instanceof Time) { Time otherTime = (Time)other; return super.equals(otherTime) && (this.hour == otherTime.hour && this.minute == otherTime.minute && this.second == otherTime.second); } else{ return false; } } // this method is very confusing. It does not do what // we intended it do when we wrote it in class. // You can ignore it, or if you are interested you // can try to see what is going on. public boolean equals(Object other1, Object other2){ System.out.println("Time equals with 2 args called"); // check if all 3 parameters are equal // better way: call the other equals twice // this is just for illustrating syntax if (other1 instanceof Time & other2 instanceof Time) { Time otherTime1 = (Time)other1; //casts needed Time otherTime2 = (Time)other2; // idea of the following was so that Date equals // will be called - but is it? Date date1 = otherTime1; //casts not needed Date date2 = otherTime2; return super.equals(otherTime1) && date1.equals(date2) && (this.hour == otherTime1.hour && this.minute == otherTime1.minute && this.second == otherTime1.second && this.hour == otherTime2.hour && this.minute == otherTime2.minute && this.second == otherTime2.second); } else{ return false; } } }