6

このパターンをどこかで見ました:

class A extends B<A> {

}

この構造は、ジェネリックの実際の型として新しい型を指定することによってジェネリックを拡張するのは少し珍しいです。用途は何ですか?このパターンに名前はありますか?代替パターンはありますか?

例: https://code.google.com/p/selenium/wiki/LoadableComponent

ジャンプ先:public class EditIssue extends LoadableComponent<EditIssue> {

編集:応答を読んだ後、コンパイラによる型チェックの理解を変える必要があるようです。私の心の奥底では、このパターンに対する私の不満は、2 つの A が同じである必要がある場合、それらを繰り返さないようにする方法はありますか? ということでした。しかし、派生クラスの型を親に伝播するより良い方法はないようです。

4

5 に答える 5

4

再帰的なデータ構造を扱うとき、このようなことをするかもしれません。たとえば、グラフまたはツリー内のノードは、他のノードのコレクションとして定義できます。

class Node extends AbstractList<Node> {
    ...
}

の場合のように、抽象/ジェネリック型が同様の型のオブジェクトを比較するためのものである場合、同様に、次のようなものが表示される場合がありjava.lang.Comparableます。

class MyObject implements Comparable<MyObject> {
    public int compareTo(MyObject other) { ... }
}
于 2013-06-14T00:10:28.693 に答える
4

もちろん、OOP の答えAB. Aが ではない場合はB、の機能を利用するために、 を使用してA自身を構成する必要があります。BB

おそらくB、ジェネリック型に課せられた制限を利用するいくつかの一般的な実装もあります。

別の使用例は、次のBようになります。

abstract class B<T extends B<T>> {
    public T createCopy(T t);
}

サブクラスを実装できるようcreateCopyになり、クライアント コードはキャストしなくても安全に使用できるようになりました...

class A extends B<A> {
    public A createCopy(A t) {
        return new A(t); //copy constructor
    }
}

上記を以下と比較してください。

abstract class B {
    public B createCopy(B t);
}
class A extends B {
    public B createCopy(B t) { //Is the copy an A or a different subtype of B? We don't know.
        return new A(t); //copy constructor
    }
}
于 2013-06-14T00:27:16.237 に答える
2

次の例を見てください。

E extends Comparable<E>

これは、 E がそれ自体と比較する方法を知っている型でなければならないことを意味します。したがって、再帰型定義です。

正式な名前があるかどうかはわかりませんが、再帰的ジェネリック型パターンと呼びます。

于 2013-06-14T00:11:27.497 に答える