これが一般的に機能しない理由と、ここでコンパイラに文句を言わせるのがなぜ良いことなのかを理解する必要があります。
ParkingLot implements Collection<Cars>
クラスand sinceがあると仮定するとCar extends Vehicle
、これにより自動的にParkingLot
も実装されCollection<Vehicle>
ます。それから私は私をに入れることができSubmarine
ましたParkingLot
。
面白くはありませんが、簡単に言えば、リンゴのコレクションは果物のコレクションではありません。果物のコレクションにはバナナが含まれる場合がありますが、リンゴのコレクションには含まれない場合があります。
これを回避する方法があります: ワイルドカードを使用することです。リンゴのコレクションは、「果物の特定のサブタイプ」のコレクションです。それがどの種類の果物であったかを忘れることで、意図したとおりになります。つまり、それが何らかの種類の果物であることがわかります。同時に、任意の果物を入れることが許可されているかどうかもわかりません。
Javaでは、これは
Collection<? extends Fruit> collectionOfFruit = bagOfApples;
// Valid, as the return is of type "? extends Fruit"
Fruit something = collectionOfFruit.iterator().next();
// Not valid, as it could be the wrong kind of fruit:
collectionOfFruit.put(new Banana());
// To properly insert, insert into the bag of apples,
// Or use a collection of *arbitrary* fruit
違いをもう一度強調しましょう。
Collection<Fruit> collection_of_arbitrary_fruit = ...;
collection_of_arbitrary_fruit.put(new Apple());
collection_of_arbitrary_fruit.put(new Banana());
果物、リンゴ、バナナを保管できる必要があります。
Collection<? extends Fruit> collection_of_one_unknown_kind_of_fruit = ...;
// NO SAFE WAY OF ADDING OBJECTS, as we don't know the type
// But if you want to just *get* Fruit, this is the way to go.
リンゴのコレクション、バナナナのコレクション、青リンゴのみのコレクション、または任意の果物のコレクションである可能性があります。どの種類の果物かはわかりませんが、ミックスである可能性があります。しかし、それらはすべてフルーツです。
読み取り専用の状況では、2 番目のアプローチを使用することを強くお勧めします。これは、特化したコレクション (「りんごのみの袋」) と幅広いコレクション (「ミックス フルーツの袋」) の両方が可能になるためです。
これを理解するための鍵は、異なる種類の A のコレクションCollection<A>
として読み取ることですが、はA の何らかのサブタイプのコレクションです(ただし、正確なタイプは異なる場合があります)。Collection<? extends A>