THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

actions that can be performed on those fields can be done via the public methods that Attr provides. On
the other hand, making the fields protected would prevent any future modifications to the implementation
of Attr because subclasses could depend on the existence and type of those fields, as well as direct access to
them. So in this case, Attr's current design is suited for extension as well as for general use.


In our linked-list queue class, SingleLinkQueue, we did make the head and tail fields protected.
In that case there was a great performance benefit in allowing the subclass to directly access cells of the linked
listit would be impractical to implement the override of add in PriorityQueue if the only tools available
to use were the original add and remove methods. The low-level nature of the SingleLinkQueue class
also means that we are not concerned about locking in implementation detailsit is after all a linked-list
implementation of a queue and that doesn't really leave much scope for change. If we had written a more
general queue class that just happened to be using a linked-list implementation, then it would be a different
story.


A non-final class has two interfaces. The public interface is for programmers using your class. The protected
interface is for programmers extending your class. Do not casually make fields of your classes protected: Both
interfaces are real contracts, and both should be designed carefully.


3.11.1. Designing an Extensible Framework


Suppose you want to provide a benchmarking harness for comparing varieties of sorting algorithms. Some
things can be said of all sorting algorithm benchmarks: They all have data on which they must operate; that
data must support an ordering mechanism; and the number of comparisons and swaps they require to do their
work is an important factor in the benchmark.


You can write an abstract class that helps you with these features, but you cannot write a general-purpose
sort methodthe actual operations of sorting are determined by each extended class. Here is a SortDouble
class that sorts arrays of double values, tracking the number of swaps, comparisons, and tests required in a
SortMetrics class we define later:


abstract class SortDouble {
private double[] values;
private final SortMetrics curMetrics = new SortMetrics();


/* Invoked to do the full sort /
public final SortMetrics sort(double[] data) {
values = data;
curMetrics.init();
doSort();
return getMetrics();
}


public final SortMetrics getMetrics() {
return curMetrics.clone();
}


/* For extended classes to know the number of elements/
protected final int getDataLength() {
return values.length;
}


/* For extended classes to probe elements /
protected final double probe(int i) {
curMetrics.probeCnt++;
return values[i];
}


/* For extended classes to compare elements /
protected final int compare(int i, int j) {

Free download pdf