...
Code Block | ||
---|---|---|
| ||
class CalendarSubclass extends Calendar { @Override public boolean after(Object when) { if(when instanceof Calendar && super.compareTo((Calendar)when) == 0) // correctly calls Calendar.compareTo() return true; return super.after(when); // calls CalendarSubclass.compareTo() due to polymorphism } @Override public int compareTo(Calendar anotherCalendar) { // This method is erroneously invoked by Calendar.after() return compareTo(anotherCalendar.getFirstDayOfWeek(),anotherCalendar); } private int compareTo(int firstDayOfWeek, Calendar c) { int thisTime = c.get(Calendar.DAY_OF_WEEK); return (thisTime > firstDayOfWeek) ? 1 : (thisTime == firstDayOfWeek) ? 0 : -1; } public static void main(String[] args) { CalendarSubclass cs1 = new CalendarSubclass(); CalendarSubclass cs2 = new CalendarSubclass(); cs1.setTime(new Date()); System.out.println(cs1.after(cs2)); // prints false } /* Implementation of other abstract methods */ } // The implementation of java.util.Calendar.after() method is shown below public boolean after(Object when) { return when instanceof Calendar && compareTo((Calendar)when) > 0; // forwards to the subclass's implementation erroneously } |
...
Code Block | ||
---|---|---|
| ||
// The CalendarImplementation object is a concrete implementation of the abstract Calendar class
// Class ForwardingCalendar
public class ForwardingCalendar {
private final CalendarImplementation c;
public ForwardingCalendar(CalendarImplementation c) {
this.c = c;
}
public boolean after(Object when) {
return c.after(when);
}
public int compareTo(Calendar anotherCalendar) {
// ForwardingCalendar's compareTo() will be called
return c.compareTo(anotherCalendar);
}
}
//Class CompositeCalendar
class CompositeCalendar extends ForwardingCalendar {
public CompositeCalendar(CalendarImplementation ci) {
super(ci);
}
@Override public boolean after(Object when) {
if(when instanceof Calendar && super.compareTo((Calendar)when) == 0)
// this will call the overridden version
// i.e. CompositeClass.compareTo();
// return true if it is the first day of week
return true;
return super.after(when); // does not compare with first day of week anymore;
// uses default comparison with epoch
}
@Override public int compareTo(Calendar anotherCalendar) {
// CompositeCalendarcompareTo() will not be called now
return compareTo(anotherCalendar.getFirstDayOfWeek(),anotherCalendar);
}
private int compareTo(int firstDayOfWeek, Calendar c) {
int thisTime = c.get(Calendar.DAY_OF_WEEK);
return (thisTime > firstDayOfWeek) ? 1 : (thisTime == firstDayOfWeek) ? 0 : -1;
}
public static void main(String[] args) {
CalendarImplementation ci1 = new CalendarImplementation();
CalendarImplementation ci2 = new CalendarImplementation();
CompositeCalendar c = new CompositeCalendar(ci1);
ci1.setTime(new Date());
System.out.println(c.after(ci2)); // prints true
}
}
|
...