1. ホーム
  2. java

[解決済み] List<Dog> は List<Animal> のサブクラスですか?Java のジェネリックはなぜ暗黙のうちに多相性にならないのですか?

2022-03-19 12:51:02

質問

Javaジェネリックがどのように継承/ポリモーフィズムを扱うのか、少し混乱しています。

以下のような階層を想定しています。

動物 (親)

- (子供)

というメソッドがあるとします。 doSomething(List<Animal> animals) . 継承とポリモーフィズムのすべてのルールによって、私は List<Dog> a List<Animal>List<Cat> a List<Animal> - であるため、このメソッドにはどちらかを渡すことができます。そうではありません。この動作を実現するには、Animalの任意のサブクラスのリストを受け取るようにメソッドに明示的に指示する必要がある。 doSomething(List<? extends Animal> animals) .

これがJavaの動作であることは理解しています。私の疑問は なぜ ? なぜポリモーフィズムは一般的に暗黙の了解になっているのに、ジェネリックになると指定しなければならないのでしょうか?

どのように解決するのですか?

いいえ List<Dog> ない a 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?

突然ですが、あなたは 非常に と戸惑う猫。

さて、あなたは できない を追加します。 CatList<? extends Animal> であることを知らないからです。 List<Cat> . 値を取得することで、その値が Animal しかし、任意の動物を追加することはできない。その逆は List<? super Animal> - を追加することができます。 Animal しかし、そこから何が読み出されるかはわかりません。 List<Object> .