Having scoured the web and found little helpful information regarding the implementation of an overridable compareTo() method, I determined myself to find a solution. In another thread I was pointed to some information pertaining to an overridable equals() method, however compareTo() has some pretty unique issues which must be overcome (namely, how to deal with objects of a related supertype, but each existing in a separate hierarchical branch). I've considered many possible scenarios and believe that I've implemented a type which allows for the modification of relational behavior by subtypes, however I'd like external verification that I'm not breaking the compareTo() contract.
public abstract class RelationalObject
implements Comparable<RelationalObject>
{
/*
* Compares two RelationalObjects for semantic ordering.
*
* @param other The RelationalObject to be compared.
*
* @return An int value representing the semantic relationship between the
* two RelationalObjects. A value of 0 is returned if the two
* objects are determined to be equal. A negative value is
* returned if "this" object is determined to have a
* lower semantic ordering than the "other" object. A positive
* value is returned if "this" object is determined to have a
* highter semantic ordering than the "other" object.
*/
public final int compareTo(RelationalObject other)
throws ClassCastException, NullPointerException
{
if (other == null)
throw new NullPointerException("other: Cannot be null.");
int relation = 0;
if (!this.equals(other))
{
if (this.getClass().isAssignableFrom(other.getClass()))
{
if (this.getClass() == other.getClass())
relation = this.compareToExactType(other);
else
/*
* Defer comparison to subtype, thereby allowing an
* optional override of compareToSuperType().
*/
relation = -1 * other.compareTo(this);
}
else
{
if (other.getClass().isInstance(this))
relation = this.compareToSuperType(other);
else
relation = this.compareToForeignType(other);
}
}
return relation;
}
/*
* Compares two RelationalObjects with the exact same class type for
* semantic ordering. The comparison may be based upon any of the class
* state elements so long as the compareTo() method contract is not
* broken.
*
* @param exact The RelationalObject with exactly matching type to be
* compared.
*
* @return An int value representing the semantic relationship between the
* two RelationalObjects.
*/
protected abstract int compareToExactType(RelationalObject exact);
/*
* Compares two RelationalObjects not within the same hierarchical branch
* for semantic ordering. The comparison may be based upon only those
* state elements common to both objects (i.e. A comparison must be made
* between each element and the pair's common ancestor). Should the two
* results be equal, a ClassCastException must be thrown as the objects do
* not contain enough distinct information to be further compared.
*
* As only one implementation exists, this should be finalized by the first
* derivative of RelationalObject.
*
* @param foreign The RelationalObject from a foreign hierarchical branch
* to be compared.
*
* @return An int value representing the semantic relationship between the
* two RelationalObjects.
*/
protected abstract int compareToForeignType(RelationalObject foreign);
/*
* Compares two RelationalObjects within the same class hierarchical
* branch for semantic ordering. The comparison may be based upon any of
* the class state elements so long as the compareTo() method contract is
* not broken.
*
* @param upper The RelationalObject within the same heirarchical branch
* and with lesser definition to be compared.
*
* @return An int value representing the semantic relationship between the
* two RelationalObjects.
*/
protected abstract int compareToSuperType(RelationalObject upper);
}