...
Code Block | ||
---|---|---|
| ||
class CalendarSubclass extends Calendar {
@Override public boolean after(Object when) {
// correctly calls Calendar.compareTo()
if (when instanceof Calendar && super.compareTo((Calendar) when) == 0) {
return true;
}
return super.after(when);
}
@Override public int compareTo(Calendar anotherCalendar) {
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();
cs1.setTime(new Date());
cs1.set( Calendar.DAY_OF_WEEK, Calendar.SUNDAY); // Date of last Sunday (before now)
CalendarSubclass cs2 = new CalendarSubclass(); // Wed Dec 31 19:00:00 EST 1969
System.out.println(cs1.after(cs2)); // expected to print true
}
// Implementation of other Calendar abstract methods
}
|
...
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;
}
CalendarImplementation getCalendarImplementation() {
return c;
}
public boolean after(Object when) {
return c.after(when);
}
public int compareTo(Calendar anotherCalendar) {
// CalendarImplementation.compareTo() will be called
return c.compareTo(anotherCalendar);
}
}
class CompositeCalendar extends ForwardingCalendar {
public CompositeCalendar(CalendarImplementation ci) {
super(ci);
}
@Override public boolean after(Object when) {
// This will call the overridden version, i.e. CompositeClass.compareTo();
if (when instanceof Calendar && super.compareTo((Calendar)when) == 0) {
// Return true if it is the first day of week
return true;
}
return super.after(when); // Does not compare with first day of week any longer;
// Uses default comparison with epoch
}
@Override public int compareTo(Calendar anotherCalendar) {
return compareDays(super.getCalendarImplementation().getFirstDayOfWeek(),
anotherCalendar.getFirstDayOfWeek());
}
private int compareDays(int currentFirstDayOfWeek, int anotherFirstDayOfWeek) {
return (currentFirstDayOfWeek > anotherFirstDayOfWeek) ?
1 : (currentFirstDayOfWeek == anotherFirstDayOfWeek) ? 0 : -1;
}
public static void main(String[] args) {
CalendarImplementation ci1 = new CalendarImplementation();
ci1.setTime(new Date());
ci1.set( Calendar.DAY_OF_WEEK, Calendar.SUNDAY); // Date of last Sunday (before now)
CalendarImplementation ci2 = new CalendarImplementation();
CompositeCalendar c = new CompositeCalendar(ci1);
System.out.println(c.after(ci2)); // expected to print true
}
}
|
Note that each method of the class ForwardingCalendar
redirects to methods of the contained CalendarImplementation
class, from which it receives return values; this is the forwarding mechanism. The ForwardingCalendar
class is largely independent of the implementation of the class CalendarImplementation
. Consequently, future changes to CalendarImplementation
are unlikely to break ForwardingCalendar
and are also unlikely to break CompositeCalendar
. Invocations of the overriding after()
method of CompositeCalendar
perform the necessary comparison by using the CalendarImplementation.compareTo()
method as required. Using super.after(when)
forwards to ForwardingCalendar
, which invokes the CalendarImplementation.after()
method as required. As a result, avajava.util.Calendar.after()
invokes the CalendarImplementation.compareTo()
method as required, resulting in the program correctly printing true
.
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="311fab662871d80d-4d6a8276-44ec4be5-8616872e-8868594180b3042214fc48bb"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] | [Class Calendar | http://download.oracle.com/javase/6/docs/api/java/util/Calendar.html] | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="adea61d74b433eab-edda58d5-42614ce3-88858ac0-29a080db6b5dcca084fac66c"><ac:plain-text-body><![CDATA[ | [[Bloch 2008 | AA. Bibliography#Bloch 08]] | Item 16: "Favor composition over inheritance" | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="7ec4dd11d719233e-71cc84c5-4bef422c-9a31964f-82a2648c52501c3d605a2299"><ac:plain-text-body><![CDATA[ | [[Gamma 1995 | AA. Bibliography#Gamma 95]] | Design Patterns: Elements of Reusable Object-Oriented Software | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="15014515f1e3e018-ae39ed41-44044251-a677a64e-a8bff97a989037f10ebe0b40"><ac:plain-text-body><![CDATA[ | [[Lieberman 1986 | AA. Bibliography#Lieberman 86]] | Using prototypical objects to implement shared behavior in object-oriented systems | ]]></ac:plain-text-body></ac:structured-macro> |
...