Вы должны понять, почему это не может работать вообще, и почему это хорошая вещь, чтобы иметь компилятор жаловаться здесь.
Предполагая, что у нас есть класс ParkingLot implements Collection<Cars>
и так 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<? 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.
Может быть коллекцией яблок, коллекция banananas, коллекция только зеленых яблок, или сбор плодов произвольных. Вы не знаете, какой тип фруктов, может быть микс. Но они все Фрукты.
только для чтения ситуации, я ясно рекомендую использовать второй подход, поскольку он позволяет как специализированные («мешок яблок только») и широкие коллекции («мешок смешанных фруктов»)
Ключ к пониманию этого читать Collection<A>
как Коллекция различного типа A, а Collection<? extends A>
- это Коллекция некоторых подтипов A (точный тип может отличаться).
В ответе на этот вопрос есть действительно хорошее объяснение: http://stackoverflow.com/questions/5082044/most-efficient-way-to-cast-listsubclass-to-listbaseclass –