3

次のコードがあります。

public class AClass<X extends AnInterface> implements AnotherInterface {

    public AClass(X x){
    }

}

XこれをAnInterface?? 確かに、それらは同じことを意味しAnInterfaceます。

すべてのパラメーター タイプをジェネリックとして保持し、「X extends AnInterface」などのジェネリック パラメトリック宣言でインターフェイス名のみに言及しようとしていますが、AnInterface タイプの渡された値が等しくないことを示しているため、問題が発生しています。タイプXに。

編集:

public void<X extends AnInterface> myMethod(){


    AnInterface b = new ADiffClass();
    AnotherInterface a = new AClass(b);
}

public class ADiffClass<X extends AnInterface> implements AnInterface {

    public ADiffClass(){
    }

}

ここで問題が発生します。b の型が AnInterface であり、AClass のコンストラクターで必要な型が X であるというコンパイル エラーが発生します。

4

5 に答える 5

6

次のような状況があるとします。

public class AClass<X extends AnInterface>{

    public AClass(X x){
        ...
    }

    public X getIt() {
        ...
    }

}

オブジェクトを作成している人は、それに応じたインターフェースを持っています。この状況では、それが役に立ちます。

例えば:

// supposing DefaultAnInstance is an implementation of AnInstance interface
DefaultAnInterface obj = new DefaultAnInterface();
AClass<DefaultAnInterface> instance = new AClass<DefaultAnInterface>(obj);
...
// for the user getIt will return an objecct of type DefaultAnInterface
DefaultAnInterface obj = instance.getIt(); // there is no need to cast it to DefaultAnInterface
于 2012-07-11T13:24:21.293 に答える
6

次のように変数を宣言すると、次のようになります。

private AClass<Foo> a;

以下が有効になります。

 a = new AClass<Foo>(new Foo());

ただし、次の場合はそうではありません。

 a = new AClass<Foo>(new Bar());

Foo(とBarが の 2 つの実装であると仮定しますAnInterface)。

その場合のジェネリックのポイントは、AnInterface を実装 (または拡張) する特定の型に型を制限することです。

于 2012-07-11T13:24:31.210 に答える
0

できなかった理由はありません。ただし、これにより、残りの汎用クラスが破損する可能性があります。

public class AClass<X extends AnInterface> {
    private X anInterface;
    public AClass(AnInterface anInterface) {
       // Not legal.  You'd have to narrow cast to X
       this.anInterface = anInterface;
    }
}

したがって、「anInterface」の宣言をXではなくAnInterfaceにいつでも変更できます。ただし、Xを参照していないため、ジェネリックスは何も提供しません。

public class AClass<X extends AnInterface> {
    private AnInterface anInterface;
    public AClass(AnInterface anInterface) {
       // Not legal.  You'd have to narrow cast to X
       this.anInterface = anInterface;
    }
}

Xの使用はどこにありますか?使用されていないジェネリックパラメーターを挿入することになります。

次に、別の回答で言及されているコンストラクターの型安全性の問題もあります。

そして、これら2つのコンストラクターは同じことを意味しません。

public AClass(AnInterface anInterface) { ... }
public AClass(X anInterface) { ... }

1つ目は、AnInterfaceと割り当て互換性のある(つまり、実装または拡張する)任意のクラスを持つことができることを意味します。2つ目は、提供されたジェネリックパラメーターと割り当て互換性のある任意のクラスを持つことができることを意味します。これは、AnInterfaceだけよりも具体的である可能性があります。誰かが上記のこの例を使用しました:

public class Int1 implements AnInterface { ... }
public class Int2 implements AnInterface { ... }
public class Int3 extends Int1 { ... }

だからあなたが持っているなら:

AClass<Int1>  --> it could accept either Int1 or Int3, but not Int2 in the constructor
AClass<Int2>  --> it could accept only Int2 in the constructor
于 2012-07-11T14:50:09.940 に答える
0

なぜインターフェースを拡張しようとしているのですか? 実装するということですか?問題は、インターフェイスを使用する必要があるクラスを使用していることだと思います。複数のクラスの何かを渡すことができるようにしたい場合、それがまさにインターフェースの目的です。

于 2012-07-11T13:23:26.037 に答える
0

AClass を考えると、平均的なジェネリックよりも汎用性を低くしたい場合があります。LinkedList などのジェネリックのように、どのタイプも処理できませんが、多くのクラスを処理できるようにしたい場合があります。

たとえば、ジェネリックなクラス SelfSortingList があるとします。ソート可能にするには、すべてのオブジェクトが比較可能である必要があります。しかし、どちらも Comparable を実装している Widgets と Levers を同じリストに入れることはできません。それは意味がなく、 Comparable の特定の実装はおそらくそれを反映しています。

つまり、「SelfSortingList で同じ型のオブジェクトを保持できるようにしたいが、それらは比較可能でなければならない」ということです。そのため、クラス ヘッダー SelfSortingList に、型パラメーター (X) と、X が可能なもの (Comparable を拡張) の制限の両方があります。

于 2012-07-11T13:43:57.907 に答える