3

初めて、関連するオブジェクト間の関係を定義しなければならなかったため、 と の完全にオーバーライド可能な実装に関する情報を求めて、週末全体を Web で探し回っていることに気付きましequals()compareTo()。役立つ情報がほとんど見つからなかったので、解決策を見つけることにしました。以下は、その解決方法の表れであると思いますcompareTo()。私は、同様の手法がこの方法でも機能する可能性があると考えていequals()ます。

私より賢い誰かが、これらの調査結果を検証し、遭遇する可能性のある落とし穴に関するフィードバックを提供する時間をとってくれることを願っています.

// The name chosen for the following class shell ("Base") is intended to
// portray that this compareTo() method should be implemented on a base class
// as opposed to a subclass.
public class Base
implements Comparable<Base>
{
    /**
     * Compares this Base to the specified Object for semantic ordering.
     *
     * @param other The Object to be compared.
     *
     * @return An int value representing the semantic relationship between the
     *         compared objects. The value 0 is returned when the two objects
     *         are determined to be equal (as defined by the equals method).
     *         A positive value may be returned if the "other" object is a
     *         Base and the "exact types" comparison determines this Base to
     *         have a higher semantic ordering than the "other" object, if the
     *         "other" object is not a Base, or if the "other" object is a
     *         subclass of Base who's compareTo method determines itself to
     *         have a lower semantic ordering than this Base. A negative value
     *         may be returned if the "other" object is a Base and the
     *         "exact types" comparison determines this Base to have a lower
     *         semantic ordering than the "other" object or if the "other"
     *         object is a subclass of Base who's compareTo method determines
     *         itself to have a higher semantic ordering than this Base.
     */
    public int compareTo(Base other)
    {
        int relationship = 0;

        if (other == null)
            throw new NullPointerException("other: Cannot be null.");

        if (!this.equals(other))
        {
            if (this.getClass() == Base.class)
            {
                if (this.getClass == other.getClass())
                    relationship = // Perform comparison of exact types;
                else
                    relationship = -1 * other.compareTo(this);
            }
            else
                relationship = 1;
        }

        return relationship;
    }
4

2 に答える 2

3

これは機能しません。直接拡張し、インスタンスが決して等しくない2 つのクラスを考えてみましょうA。次に、2 つのインスタンスと. は との両方に対応するので、もも も となります。これは、すべてのための一般的な契約に違反し、比較可能です。BBaseBase a = new A();Base b = new B()this.getClass() == Base.classfalseaba.compareTo(b) == 1b.compareTo(a) == 1Comparablesgn(x.compareTo(y)) == -sgn(y.compareTo(x))xy

オブジェクトの比較、特にサブクラス間の同等性のテストに伴う微妙な点については、この優れた記事をお勧めします。

于 2012-07-30T07:18:56.980 に答える
0

compareTo()トピック スターターで述べたように、クリーンにオーバーライド可能なメソッドの構築の背後にあるプロセスを詳述する利用可能な情報が不足しているため、このプロジェクトを開始しました。以下がそのような実装であることがわかると思います。私が最初に見落としていたいくつかの重要な要素を指摘してくれた Ted Hopp に補足します。

RelationalObject の実装では、同じ階層分岐以外の要素間の初期関係が定義されていないことがわかります。これは、比較不可能であると見なされます (もちろんオーバーライド可能です)。このクラスが実装する可能性のある関係は、その派生クラスの状態要素を考慮に入れることができないため、このタスクはユーザーのみに任せるのが最善であると判断しました。

このクラスが意図していることは、新しいサブタイプ (現在実装されていないものを含む) のリレーショナル動作を簡単に変更できるようにすることです。

トピックのスターターでドキュメントを作成したいという要望を表明したので、何らかのガイダンスが得られることを期待して、各メソッドに十分なコメントを付けました。

十分な時間のある人がこれらの結果の検証を進んで提供してくれることを願っています. 考えられるすべての状況を検討するために最善を尽くしましたが、フィードバックを得るのはいつでも良いことです。(正または負)

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
                    relation = -1 * other.compareTo(this);
            }
            else
            {
                if (other.getClass().isInstance(this))
                    relation = this.compareToSuperType(other);
                else
                    relation = other.compareToForeignType(this);
            }
        }

        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.
     *
     * @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);
}
于 2012-08-01T05:44:53.003 に答える