The preceding Java program can be improved by eliminating duplicated code. Note that the fields name, address, and phone appear in all three concrete subclasses of the abstract class CityEntry. So do definitions of the corresponding accessors getName, getAddress, and getPhone. These repeated member definitions can be hoisted into the abstract class CityEntry yielding the following Java code:
abstract class CityEntry { String name; String address; String phone; /* accessors */ String getName() { return this.name; } String getAddress() { return this.address; } String getPhone() { return this.phone; } } class BusinessEntry extends Entry { String city; String state; /* constructor */ BusinessEntry(String n, String a, String p, String c, String s) { this.name = n; this.address = a; this.phone = p; this.city = c; this.state = s; } /* accessors */ String getCity() { return this.city; } String getState() { return this.state; } } class GovernmentEntry extends Entry { String city; String state; String government; /* constructor */ GovernmentEntry(String n, String a, String p, String c, String s, String g) { this.name = n; this.address = a; this.phone = p; this.city = c; this.state = s; this.government = g; } /* accessors */ String getCity() { return this.city; } String getState() { return this.state; } } class ResidentialEntry extends Entry String address; String phone; /* constructor */ ResidentialEntry(String n, String a, String p) { this.name = n; this.address = a; this.phone = p; } }
Finger Exercise By applying some very simple program transformations,
you can eliminate more code duplication in the CityEntry class
and subclasses. Note that the subclasses BusinessEntry
and GovernmentEntry include common fields and accessors.
Introduce a new abstract class NonResidentialEntry extending
CityEntry to hold these common class members.
After this addition, the class CityEntry still has only three
concrete subclasses but only one of them is an immediate
subclass. The other immediate subclass is NonResidentialEntry.
Test your code using Drjava.
Optional Finger Exercise Note that the constructor for each
concrete subclass of CityEntry replicates the code for
initializing the fields address and phone defined in the
abstract class CityEntry. Similarly, the constructor for each
concrete subclass of NonResidentialEntry replicates code for
initializing the fields city and state. This
code replication can be eliminated by defining constructors
for the abstract classes CityEntry and NonResidentialEntry
and using ``super calls'' to invoke these
constructors at the beginning of each concrete class constructor.
In the body of a constructor for a class C, the reserved word super can be used as a method name to to invoke a constructor in the superclass of C. In such an invoccatation, the method name super must be followed by an appropriate argument list enclosed in parentheses just like any other method call. (For more information on super calls, consult either as The Java Programming Language by Arnold and Gosling or Java in a Nutshell by Flanagan.)
Eliminate constructor code replication in the CityEntry class hierarchy. Test your code using DrJava.
Member hoisting is a special form of the general concept of code factoring. Code factoring is any transformation that eliminates repeated code. In functional languages like Scheme, the standard code factoring is typically accomplished by introducing a new -abstraction with a repeated code pattern as its body. Each instance of the repeated pattern is replaced by an appropriate call on the new abstraction. In some cases, the arguments to the pattern are procedures. This form of code factoring can be implemented in several different ways in Java. If all of the code repetitions appear within a class hierarchy for the programmer has control of the source, then a method can be introduced in the most restrictive subclass that includes all of the intances of the repeated pattern. Each instance can be replaced by an invocation of the introduced method. In some cases, the arguments to the method are command objects (discussed in Section 1.9) representing procedures.