2017-07-20 11 views
1

私は食事を作るレストランを持っています。キッチンには、消費者向けのプレートが用意されています。PECS:コンシューマをプロデューサに変換する方法は?

class Food{} 
class Bamboo extends Food {} 

interface Kitchen { 
    void build(List<? super Food> dessert); 
} 

abstract class Restaurant { 
    Kitchen kitchen; 

    public Restaurant(Kitchen kitchen) { 
     this.kitchen = kitchen; 
    } 

    List<? extends Food> getMeals() { 
     List<Food> food = new ArrayList<>(); 
     this.kitchen.build(food); 
     return food; 
    } 
} 

class PandaKitchen implements Kitchen{ 

    // Exact signature of the Kitchen 
    @Override 
    public void build(List<? super Food> plate) { 
     // the List IS a consumer of bamboos 
     plate.add(new Bamboo()); 
    } 
} 

// Bamboo specialized restaurant 
class OhPanda extends Restaurant { 

    public OhPanda() { 
     super(new PandaKitchen()); 
    } 

    // Specialized signature of List<? extends Food> 
    @Override 
    List<Bamboo> getMeals() { 
     List<? super Food> bamboos = new ArrayList<>(); 
     this.kitchen.build(bamboos); 

     // Obviously here, there is no information of having only Bamboos 
     return bamboos; // <==== FAIL 

     //return (List<Bamboo>) bamboos; // would not compile 
    } 
} 

最後の行では、私のOhPandaレストランがBamboosを生産していることを知っています。 List<? super Food>をメモリに作成/コピーせずに変換するベストプラクティスは何ですか?

より完全な要旨はここに書かれている:https://gist.github.com/nicolas-zozol/8c66352cbbad0ab67474a776cf007427

答えて

1

または、レストランとキッチン?

package kitchen; 

import java.util.ArrayList; 
import java.util.List; 

class Food{} 
class Bamboo extends Food {} 

interface Kitchen<F> { 
    void build(List<F> dessert); 
} 

abstract class Restaurant<T> { 
    protected Kitchen kitchen; 

    Restaurant(Kitchen kitchen) { 
     this.kitchen = kitchen; 
    } 

    List<T> getMeals() { 
     List<T> food = new ArrayList<>(); 
     kitchen.build(food); 
     return food; 
    } 
} 

class PandaKitchen implements Kitchen<Bamboo>{ 

    @Override 
    public void build(List<Bamboo> dessert) 
    { 
     dessert.add(new Bamboo()); 
    } 
} 

/** Bamboo specialized restaurant*/ 
class OhPanda extends Restaurant<Bamboo> { 

    OhPanda() { 
     super(new PandaKitchen()); 
    } 

    @Override 
    List<Bamboo> getMeals() { 
     List<Bamboo> bamboos = new ArrayList<>(); 
     kitchen.build(bamboos); 
     return bamboos; 
    } 
} 
+0

私は別の解決策を追加しました。 –

+0

これはうまくいきましたが、TとFがFoodを拡張しているところで、ちょっとした解決策を作りました:https://gist.github.com/nicolas-zozol/37748839e4bcfeaaf7cec914fb2442ce –

+0

なぜthis.kitchen.build(bamboos);どのようにvoidビルド(リストプレート); '以前ビルドビルド(リスト<?スーパー食品>プレート);'これらのバンブーを受け入れなかったときにバンブーを受け入れることができますか? –

1

私はあなたが低境界ワイルドカードの間違った使用をすると思います。あなたはあなたのワイルドカードのクラスをあなたの実装に指定しないことによって直面する可能性のあるUpper Boundedワイルドカードの制限への回り道としてそれを使います。私はあなたが食べ物とそのスーパータイプで作業したいとは思わない。あなたはFoodとその派生物を扱うだけで、 "?extends Food"を使って解決策を見つけたり、ワイルドカードを取り除いてリストを使用したりする必要があります。< Food>

+0

これはできません。 'List 'は 'List <? 'ではありません。スーパーフード>。それは2つの異なるタイプとして捕捉されます。 –

+0

確かに、私の悪い。私の投稿を編集しました。 – Maaaatt

関連する問題