Что такое использование вызова виртуального метода Java?
Я понимаю, что является вызовом метода java и практиковал многие примеры, используя его.
Я хочу знать, какова практическая ситуация или необходимость этой концепции.
Было бы очень полезно, если бы кто-нибудь мог дать сценарий реального мира, где он используется, и
что произойдет, если бы эта концепция не была там?
Ответы
Ответ 1
Вот пример. Предположим, что у нас есть 2 класса:
class A {
public String getName() {
return "A";
}
}
class B extends A {
public String getName() {
return "B";
}
}
Если мы сейчас сделаем следующее:
public static void main(String[] args) {
A myA = new B();
System.out.println(myA.getName());
}
получаем результат
B
Если у Java не было virtual method invocation
, во время компиляции было бы определено, что вызываемый getName()
является тем, который принадлежит классу A
. Поскольку это не так, но определяет это во время выполнения в зависимости от фактического класса, на который указывает myA
, мы получаем приведенный выше результат.
[EDIT добавить (слегка надуманный) пример]
Вы можете использовать эту функцию для записи метода, который принимает любое количество аргументов Object
в качестве аргумента и печатает их следующим образом:
public void printObjects(Object... objects) {
for (Object o: objects) {
System.out.println(o.toString());
}
}
Это будет работать для любого сочетания объектов. Если у Java не было virtual method invocation
, все объекты будут напечатаны с использованием Object's toString()
, который не очень читаем. Вместо этого будет использоваться toString()
каждого фактического класса, что означает, что распечатка обычно будет более читаемой.
Ответ 2
ОК, я попытаюсь привести простой пример. Вы пишете метод, который заполнит список, предоставленный вызывающим абонентом:
public void fill(List l) {
list.add("I just filled the list!");
}
Теперь один вызывающий абонент хочет использовать связанный список; другой предпочитает реализацию списка на основе массива. Будут другие абоненты с еще большим количеством реализаций списков, о которых вы даже не слышали. Это совершенно разные объекты. Предложите решение, которое достигает этого , не полагаясь на виртуальные методы.
Без виртуальных методов это означало бы, что тип List
уже должен был реализовать метод add
. Даже если у вас есть подтип ArrayList
, у которого был переопределенный метод, компилятор (и среда выполнения!) Просто проигнорирует этот метод и использует его в List
. Было бы невозможно использовать разные реализации List
, которые соответствуют одному и тому же интерфейсу; было бы невозможно повторно использовать эту строку кода в методе fill
, так как он будет работать только с методом в типе List
.
Итак, вы видите, что вся идея иерархии типов не имеет большого смысла; interface
и abstract class
es даже не существовало. Вся Java распадается на осколки без этой функции виртуальных методов.