4

このSO ディスカッションでは、次のイディオムを提案しています。

public interface IComparable<T extends IComparable<T>> {
    int compare(T t);
}

次に許可します:

public class Foo implements IComparable<Foo> {
    public int compare(Foo foo) {
        return 0;
    }
}

ただし、このイディオムでは、次のコードもコンパイルされるため、上記以外のことも可能です。

class A implements IComparable<A> {
    public int compare(A a) {return 0;}
}

public class Foo implements IComparable<A> {

    public int compare(A a) {
        return 0;
    }
}

したがって、(私が何かを誤解していない限り)元のイディオムは、はるかに劇的ではないイディオムと比較して、実際には何も購入しません。

public interface IComparesWith<T> {
    int compare(T t);
}

public class A implements IComparesWith<A> {
    public int compare(A a) {...}
}

では、上記のような抜け穴なしで、実装を宣言するクラスが独自のクラスのオブジェクトと比較するメソッドを持つように、実際にインターフェイスを宣言する方法はありますか?

上記をコメントとして投稿できなかったため、新しい投稿を作成しました。

4

5 に答える 5

6

いいえ、そのような制限は、書かれているジェネリックでは不可能です。あなたの評価は私には正しいようです。

于 2013-08-31T23:09:50.103 に答える
5

その通りです。このイディオムは、クラスが異なるクラスと比較されることを妨げません。比較対象のオブジェクトも同じインターフェイスを実装していることを確認するだけです。同じ型のみを比較する必要がある場合は、実装クラスによって強制できます。

あなたが「抜け穴」と呼んでいるものは、私が「やりたくないことを故意に行うこと」と呼んでいるものです。

Fooオブジェクトは、そのような動作が必要な場合Aオブジェクトと比較できます。

これは機能であり、抜け穴ではありません。

Fooを他のFooと比較できるようにしたい場合は、実装するFooを定義する必要があります。IComparable<Foo>

FooをAと比較したくない場合は、Fooを implement に定義しないでください。故意に壊れたコードを書こうとしない限り、なぜそんなことをするのでしょうか?IComaparable<A>

あなたの質問に対する実際の回答は、@caskey によって既に提供されています。

いいえ、Java のインターフェイスを使用してやりたいことを行うことはできません。[クラスで行う必要があります]。

見逃したことが 1 つあります。

したがって、(私が何かを誤解していない限り)元のイディオムは、はるかに劇的ではないイディオムと比較して、実際には何も購入しません。

public interface IComparable<T>

オリジナルのイディオム あなたに何かをもたらします。比較対象のオブジェクトがIComparableを実装する必要があることを強制します。劇的ではない例では、実装クラスを任意のオブジェクトと無制限に比較できます。だから...コンパイラは、型パラメータとして、または、または、または何でも指定できるようにします。LongInputStreamLinkedHashSet<Byte[]>

そのように見ると、このイディオムが非常に一般的である理由が簡単にわかります。

于 2013-09-01T01:04:18.207 に答える
3

したがって、(私が何かを誤解していない限り)元のイディオムは、はるかに劇的ではないイディオムと比較して、実際には何も購入しません。

それは何かを買いますが、それはあなたが考えているものとは別のものです。そして、誰かがそれを書いたとき、99.9% の確率で、それは彼らが買おうとしているものではありません。

では、上記のような抜け穴なしで、実装を宣言するクラスが独自のクラスのオブジェクトと比較するメソッドを持つように、実際にインターフェイスを宣言する方法はありますか?

いいえ。タイプ セーフの観点からは役に立たないためです。に問題はありませんpublic class Foo implements IComparable<A>-- 完全にタイプ セーフです。Foo何らかの方法で安全に比較できるを作成したい人がいればA、それは素晴らしいことです。私はjahroy'aの答えに同意します-それは「抜け穴」ではありません。それは特徴です。安全である限り、より一般的なものにしないのはなぜですか? 何をするにも邪魔になりません。すべてのクラスを自分自身と比較したい場合は、それも問題ありません。タイプセーフである限り、すべて問題ありません。

型とそれが実装する型パラメーターの関係を気にする必要がある唯一の場所は、それIComparable使用する場所です。したがって、その場所 (同等の型によってパラメーター化されるジェネリック クラスまたはジェネリック メソッド) では、次のように同等の型を表す型変数を簡単にバインドできます。これにより、それ自体と比較できるT extends IComparable<? super T>ことを保証できます。T

于 2013-09-01T02:02:24.263 に答える
-1

ジェネリックを使用しないでください:

public interface Foo {
    public void doSomething(Foo foo);
}
于 2013-08-31T23:05:37.077 に答える
-4

それはそう。Thisそのような型パラメーターの従来の名前として使用することをお勧めします

public interface IComparesWith<This> 
{
    int compare(This t);
}

私の以前の回答:実装者を指す汎用インターフェイスを作成する便利な方法

于 2013-08-31T23:21:01.567 に答える