2011-09-13 18 views
2

次のインターフェイスを検討してください。インターフェイスからのアダプタ<Type>からインターフェイス<Subtype>

public interface Feed<T> { 

    public void put(T o); 

} 

私たちは、特定のコレクションにオブジェクトを書き込むこのインターフェイスを実装する簡単なJavaクラスを持っています。

public class CollectionFiller<T> implements Feed<T> { 

    private final Collection<T> collection; 

    private CollectionFiller(Collection<T> collection) { 
     this.collection = collection; 
    } 

    public void put(T o) { 
     this.collection.add(o); 
    } 

    public static <T> CollectionFiller<T> of(Collection<T> collection) { 
     return new CollectionFiller<T>(collection); 
    } 

} 

ここでは、質問を具体的にするために2つのダミークラスを定義します。

public class Super {} 

public class Sub extends Super {} 

のは、いくつかの方法writeSubsTo(Feed<Sub> f)があるとしましょう、私たちは、インスタンスCollectionFiller<Super>cfを持っています。 cfは "Supers"のコレクションにオブジェクトを追加するだけなので、writeSubsToに渡すことは安全です。コンパイラはそれを許可しません。

タイプXのCollectionFillerを囲み、タイプXの特定のサブタイプのFeedとしてポーズする便利なアダプタを書きたいと思っていました。物事)次の、しかしコンパイラは私にトラブルを与える。

class SubFiller<T1, T2 extends T1> implements Feed<T2> { 

    private final CollectionFiller<T1> collectionFiller; 

    SubFiller(CollectionFiller<T1> collectionFiller) { 
     this.collectionFiller = collectionFiller; 
    } 

    public void put(T2 o) { 
     this.collectionFiller.put(o); 
    } 

    public static <T1, T2 extends T1> SubFiller<T1, T2> of(CollectionFiller<T1> c) { 
     return new SubFiller<T1, T2>(c); 
    } 

} 

このクラスに問題はありませんが、コンパイラは次のコードフラグメントの最後の2つのステートメントの両方を受け入れません。

CollectionFiller<Super> cf = CollectionFiller.of(new HashSet<Super>()); 
SubFiller<Super, Sub> sf = SubFiller.of(cf); 
writeSubsTo(SubFiller.of(cf)); 

誰もこの問題を解決する良い方法を考えることができますか?アダプターに厄介なコードが含まれていても、それを使用することはあまり冗長ではないので、私は気にしません(したがって、静的ファクトリーメソッド)。もちろん、他のソリューション(アダプタを使用しない)でも問題ありません(これはあまり冗長ではありません)。

答えて

7

writeSubsTo(Feed<? super Sub> f)を使用する場合は、Feed<Super>を渡すことができます。それから、フィラークラスを一掃することができます。よろめい! :-P

(共変バージョン、? extends Xあなたはかなりの値を置くよりも値がアウトを取得している場合のために、もあります。)

+2

そんなにタイピングは、そのような簡単な解決策;-)グレート、ありがとう! – Rinke

関連する問題