Я изучаю системы типов и столкнулся со следующим упражнением:
interface Food{}
interface Plant extends Food{
void photosyntes();
}
interface Animal extends Food{
void eat(Food food);
}
Мы хотели бы реализовать интерфейс Carnivore
, расширяющий Animal
. Его eat
метод будет принимать только экземпляры Animal. Это ограничение должно применяться системой типов, а не динамической проверкой. Объясните, почему это нельзя сделать, используя приведенное выше определение интерфейса.
В Java тип массива Animal[]
является подтипом Food[]
. В общем, если S является подтипом T, то S [] является подтипом T []. Это правило требует, чтобы проверка типа времени выполнения выполнялась в каждом хранилище массива. Опишите ситуацию, когда, если эта проверка во время выполнения не была выполнена, массив Animal[]
мог бы содержать Plant
. Проиллюстрировать с помощью кода Java.
Моя интуиция заключается в том, что эта проблема связана с ковариацией и контравариантностью, но я не могу дать исчерпывающее объяснение.
Это потому, что мы должны использовать классы вместо интерфейсов? Можно ли использовать другую интерфейсную систему для этого?