2013-08-23 5 views
8

私が持っているオブジェクトは、自分自身のコピーを作成することができますが保証インタフェースは:サブクラス

public interface Duplicable<T extends Duplicable<T>> { 
    public T duplicate(); 
} 

私は今

class X implements Duplicable<X> 

持っていますが、私はまた、X.

を拡張するクラスのYを持っています

別の汎用クラスが必要になるまで、これは問題ではありません。

public class DoStuffWithDuplicable<T extends Duplicable<T>> 
それはX.

からそれを継承しているので、それはDuplicable<Y>が、Duplicable<X>を実装していないので、私はだから私は

public class DoStuffWithDuplicable<T extends Duplicable<? super T>> 

を試してみました..しかし、この手段、Yを使用してDoStuffWithDuplicableのジェネリック版を使用することはできません

後で危険なキャストを導入する

(T) obj.duplicate() 

また、クラスパラメータはより複雑であり、クラスの使用法は理解しにくい。任意のアイデアはどのようにこの問題を回避するには?

+0

あなたはこれを言い換えることができます:「それがないので、私は、Yを使用してDoStuffWithDuplicableのジェネリック版を使用することはできませんDuplicableを実装していないが、DuplicableはXから継承しているため。 ? – tbsalling

+0

申し訳ありません、書式設定の問題 – phil

+1

これはまさに、一部のコンピュータ科学者がすべてのクラスを「抽象的」または「最終的」であると言う理由のようなものです。あなたは 'equals'でも問題に遭遇します。あなたはインスタンス化可能な 'X'を排除するためにおそらくリファクタリングできますか? – chrylis

答えて

1

私はあなたの質問を正しく理解していないかもしれませんが、私はそれを行っていきます。

まず、どうしてそのように拡張されたインターフェイスがあるのですか?

あなたが試すことができることはこれです:ときに今

public class X<T extends Duplicable<T>> { 
    code... 
} 

:あなたは、一般的なパラメータが複製できるようにしたい別のクラスを使用する場合

public interface Duplicable<T> { 
    public T duplicate(); 
} 

はその後、あなたはこのようにそれを行いますXから継承すると、サブクラスの汎用コンポーネントはすべてDuplicableでなければなりません。

+1

私は「なぜ」を考えますOPはそれを実装するクラスと同じ型に 'T 'を制約したいと考えています。あなたの方法では、例えば 'Integer'が' Duplicable 'を実装することができます。 –

+0

@MarkoTopolnik:1)しかし、OPの制約はそれを制約しません。それを拘束することはできません。 2)そして、OPの制約は、とにかくタイプセーフな目的を果たさない。インターフェイスはそのままタイプセーフです。 '列挙は' 延び>を: – newacct

+0

バウンド 'を拡張>' 'T' Enum'は、その型パラメータを制約 'と同様制約します。 'E'はenumクラスそのものでなければなりません。 –

1

Javaではこれを行うことはできません。

タイプYのオブジェクトに対してobj.duplicate()を呼び出すとします。次に、タイプシステムは、YがDuplicate <X>を実装するため、タイプXのオブジェクトを返すことを保証します。

ただし、DoStuffWithDuplicable <X>を作成してYオブジェクトを渡すことができます。

DoStuffWithDuplicable<X> blub = new DoStuffWithDuplicable<X>(); 
    Y y = (Y) blub.doStuff(new Y()); 

戻り値として、ライブラリのクライアントは、具体的な型を知っている可能性があるので、安全なキャストを使用できます。

他のオプションは、ライブラリ内の危険なキャストを使用して、手動タイプを確認するには、次のようになります。

class DoStuffWithDuplicable<T extends Duplicable<? super T>> { 
    T doStuff(T obj) { 
     @SuppressWarnings("unchecked") 
     T t = (T) obj.duplicate(); 
     if (!t.getClass().equals(obj.getClass())) 
      throw new ClassCastException("..."); 
     return t; 
    } 
}