Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#FFCCCC
class CalendarSubclass extends Calendar {
  @Override public boolean after(Object when) {
    // correctly calls Calendar.compareTo()
    if(when instanceof Calendar && super.compareTo((Calendar)when) == 0) { // Note the == operator
      return true;
    }
    return super.after(when); // Calls CalendarSubclass.compareTo() instead of Calendar.compareTo() 
  }
	
  @Override public int compareTo(Calendar anotherCalendar) {
    // This method is erroneously invoked by Calendar.after()
    return compareDays(this.getFirstDayOfWeek(), anotherCalendar.getFirstDayOfWeek());
  }

  private int compareDays(int currentFirstDayOfWeek, int anotherFirstDayOfWeek) {
    return (currentFirstDayOfWeek > anotherFirstDayOfWeek) ?
           1 : (currentFirstDayOfWeek == anotherFirstDayOfWeek) ? 0 : -1;
  }

  public static void main(String[] args) {
    CalendarSubclass cs1 = new CalendarSubclass(); 
    CalendarSubclass cs2 = new CalendarSubclass(); // Wed Dec 31 19:00:00 EST 1969
    cs1.setTime(new Date());                       // Current day's 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; // Note the > operator
     // forwards to the subclass's implementation erroneously
}

...

Note that each method of the class ForwardingCalendar redirects to methods of the contained class instance (CalendarImplementation), and receives back return values. This is the forwarding mechanism. This The ForwardingCalendar class is largely independent of the implementation of the class CalendarImplementation. Consequently, any future changes to the latter will not break ForwardingCalendar and in turn CompositeCalendar, which inherits derives from ForwardingCalendarit. When CompositeCalendar's overriding after() method is invoked, it performs the necessary comparison by using the local version of the compareTo() method as required. Using super.after(when) forwards to ForwardingCalendar which invokes the CalendarImplementation's after() method. In this case, CalendarImplementation's compareTo() method gets called instead of the overriding version in CompositeClass that was inappropriately called in the noncompliant code example.

...