Тесты Пообщаться с GPT Протестировать код
Программирование Аналитика Дизайн Маркетинг Управление проектами
08 Ноя 2023
2 мин
345

Полиморфизм и обобщения в Java

Пройдите тест, узнайте какой профессии подходите

В Java существует понятие наследования и полиморфизма. Это означает, что если у нас есть класс Animal, а классы Dog и Cat являются его наследниками, то мы можем

В Java существует понятие наследования и полиморфизма. Это означает, что если у нас есть класс Animal, а классы Dog и Cat являются его наследниками, то мы можем считать, что Dog и Cat являются подтипами Animal. Таким образом, где бы не требовался Animal, мы можем использовать Dog или Cat.

Например, если у нас есть метод move(Animal animal), мы можем вызвать этот метод с объектами типов Dog и Cat, так как они являются подтипами Animal.

Однако проблема возникает, когда мы начинаем работать с обобщениями (generics) в Java. Предположим, у нас есть метод checkAnimals(List<Animal> animals). Можно ли передать в этот метод List<Dog> или List<Cat>? Ведь Dog и Cat являются подтипами Animal. Оказывается, что это невозможно.

List&lt;Dog&gt; dogs = new ArrayList&lt;&gt;();
checkAnimals(dogs); // ошибка компиляции

Причина этого кроется в том, как Java обрабатывает обобщения. В обобщениях полиморфизм не работает неявно, и List<Dog> не считается подтипом List<Animal>. Если бы это было так, то мы могли бы добавить Cat в список dogs, что ведет к противоречию и ошибкам во время выполнения.

List&lt;Animal&gt; animals = dogs; // если бы это было допустимо...
animals.add(new Cat()); // ...то мы могли бы добавить Cat в список собак!

Чтобы обойти это ограничение и позволить передавать List<Dog> и List<Cat> в checkAnimals, в Java используется конструкция List<? extends Animal>. Это говорит компилятору, что мы можем передать список любого подтипа Animal.

void checkAnimals(List&lt;? extends Animal&gt; animals) { /* ... */ }

List&lt;Dog&gt; dogs = new ArrayList&lt;&gt;();
List&lt;Cat&gt; cats = new ArrayList&lt;&gt;();

checkAnimals(dogs); // теперь это работает
checkAnimals(cats); // и это тоже

В этом случае мы все еще не можем добавить Cat в список dogs, потому что компилятор не знает точный тип, который используется вместо ?.

Таким образом, полиморфизм в обобщениях Java работает несколько иначе, чем мы могли бы ожидать, и требует явного указания при использовании.

Добавить комментарий