Java ジェネリックが継承/ポリモーフィズムをどのように処理するかについて少し混乱しています。
次の階層を想定する -
動物(親)
犬-猫(子供)
メソッド があるとしますdoSomething(List<Animal> animals)
。継承とポリモーフィズムのすべてのルールにより、 a はa でList<Dog>
ありList<Animal>
、 aはaList<Cat>
であるList<Animal>
と想定されるため、このメソッドにはどちらも渡すことができます。しかし、そうではありません。この動作を実現するには、 と記述して、メソッドに Animal の任意のサブクラスのリストを受け入れるように明示的に指示する必要がありますdoSomething(List<? extends Animal> animals)
。
これは Java の動作だと理解しています。私の質問はなぜでしょうか。ポリモーフィズムは一般に暗黙的であるのに、ジェネリックの場合は指定する必要があるのはなぜでしょうか。
ベストアンサー1
いいえ、 は ではList<Dog>
ありませんList<Animal>
。 で何ができるか考えてみましょう。 にはどんなList<Animal>
動物でも追加できます...猫も追加できます。では、論理的に子犬の群れに猫を追加できますか? 絶対にできません。
// Illegal code - because otherwise life would be Bad
List<Dog> dogs = new ArrayList<Dog>(); // ArrayList implements List
List<Animal> animals = dogs; // Awooga awooga
animals.add(new Cat());
Dog dog = dogs.get(0); // This should be safe, right?
突然、非常に混乱した猫ができました。
ここで、を に追加することはできません。が であるかどうかわからないからです。 値を取得して になることはわかりますが、任意の animal を追加することはできません。 についてはその逆が当てはまります。その場合、 を に安全に追加できますが、 である可能性があるため、 から何が取得されるかについては何もわかりません。Cat
List<? extends Animal>
List<Cat>
Animal
List<? super Animal>
Animal
List<Object>