Я не могу получить доступ к методам конкретного класса полиморфно
У меня есть интерфейс MyInterface с двумя методами doSomething() и doSometingElse().
У меня есть абстрактный публичный класс A, который реализует этот интерфейс. У меня есть класс C, который расширяет класс A и, следовательно, также реализует методы интерфейса. В методе main я назначаю объект класса C для ссылки MyInterface, например: MyInterface myiface = new C();
Проблема в том, что если я добавлю некоторые методы в один из классов (абстрактный или конкретный), я не смогу вызвать метод через ссылочный myiface. Я должен унизить это сначала. Разве я не должен иметь возможность полиморфного доступа к классу, как это показано в книге Java SE8 для программистов Deitel (глава 10 Полиморфизм и интерфейс)?
2 ответа
Разве я не должен иметь возможность полиморфно получить доступ к классу...
Вы могли бы - если бы тип вашей переменной был типа C
, Но это не так, это типа MyInterface
и это полностью определяет, к каким функциям экземпляра у вас есть доступ. Да, экземпляр имеет больше возможностей, но код, записанный в интерфейс, не знает этого.
Добавление функций в C
имеет мало общего с полиморфизмом. В этом случае полиморфизм (есть несколько разных его видов) заключается в том, что A
а также C
мог бы реализовать MyInteface
функции по- разному, но ваш код, используя экземпляры через MyInterface
ссылка не знает и не заботится о том, что экземпляры A
с или C
s; все, что он знает, все, что он должен знать, - это то, что они утверждают, что являются верными реализациями MyInterface
,
Давайте возьмем конкретный пример:
public void doSomethingWith(List list) {
// ...
}
Когда что-то звонит doSomethingWith
, это проходит в случае, который выполняет List
интерфейс. Это все, что этот метод знает об экземпляре (отсутствуют такие вещи, как instanceof
а также getClass
). Экземпляр может быть ArrayList
, LinkedList
, Stack
, так далее.; но код, использующий его, не знает и не заботится об этом. Все, что он знает, это то, что это List
, Даже если метод передан ArrayList
не может использовать (скажем) ensureCapacity
без предварительного уменьшения ссылки (что не удастся, если экземпляр не ArrayList
), потому что не все List
реализации имеют ensureCapacity
,
Подумайте об этом так... представьте, что ваш MyInterface называется "Animal", и у вас есть два класса, реализующих его, "Dog" и "Cow". только потому, что они оба животные, вы не ожидаете, что Собака внезапно даст молоко, верно? В этой аналогии метод giveMilk() реализован только классом Cow.
ты понял?