...
Wiki Markup |
---|
This compliant solution uses a design pattern called composition and forwarding (sometimes also referred to as delegation) \[[Lieberman 1986|AA. Bibliography#Lieberman 86]\] \[[Gamma 1995|AA. Bibliography#Gamma 95], p. 20\]. The compliant solution introduces a new _forwarder_ class that contains a {{private}} member field of the {{Calendar}} type; this is _composition_ rather than inheritance. In this example, the field refers to {{CalendarImplementation}}, a concrete instantiable implementation of the {{abstract}} {{Calendar}} class. The compliant solution also introduces a wrapper class called {{CompositeCalendar}} that provides the same overridden methods found in the {{CalendarSubclass}} from the preceding noncompliant code example. |
Code Block | ||
---|---|---|
| ||
// Theclass CalendarImplementation objectextends isCalendar 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 } } |
...
Modifying a superclass without considering the effect on subclasses can introduce vulnerabilities. Subclasses that are unaware developed without awareness of the superclass implementation can be subject to erratic behavior, resulting in inconsistent data state and mismanaged control flow.
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="ca8c00357a2ffe6b-804563e6-49c74ade-9a959004-3a775bf6d204f5ec0c853ac9"><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="c0c136daecadbf7e-a77083de-49af4358-8eb68e63-67c75b8957ead033d1df20bc"><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="3d15ea021230a703-9c2815d6-4b314403-ac6aad22-ff275990d1d30beec61da528"><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="7e01c9b0c9bf24e5-92cbb068-48de4d77-b129b31b-6990b55766c819c1acf24c3b"><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> |
...