To support a notion of ordering for sorting objects, the classes of
these objects must implement a method for ordered comparisons of
themselves with other objects.  The following abstract class
"Comparable" provides such a method:

/**
 * Comparable objects support a meaning for ordered comparisons with
 * other objects of the same class.
 */
abstract class Comparable {
    /**
     * Compare this object with another; return a negative integer if this
     * object is less than the supplied object, zero if the two objects
     * are equal, and a positive number if this object is greater.
     */
    public abstract int compare(Comparable obj);
}

Note that this requires all classes that may be sorted to extend,
directly or indirectly, the Comparable class, and because Java only
allows single class inheritance, this places a severe restriction on
the kinds of objects that can be sorted this way.  A much more
flexible solution would be to make Comparable an "interface"; see
Exercise 4.2.  Here is the code for the SortHarness class:

abstract class SortHarness {
    private Comparable[] values;
    private SortMetrics curMetrics = new SortMetrics();

    /** Invoked to do the full sort --
     *  objects to be sorted must support ordered comparison */
    public final SortMetrics sort(Comparable[] data) {
	values = data;
	curMetrics.init();
	doSort();
	return metrics();
    }

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

    protected final int dataLength() {
	return values.length;
    }

    /** For derived classes to compare elements */
    protected final int compare(int i, int j) {
	curMetrics.compareCnt++;
	return values[i].compare(values[j]);
    }

    /** For derived classes to swap elements */
    protected final void swap(int i, int j) {
	curMetrics.swapCnt++;
	Comparable tmp = values[i];
	values[i] = values[j];
	values[j] = tmp;
    }

    /** Derived classes implement this -- used by sort() */
    protected abstract void doSort();
}

