Что такое вызов виртуального метода в java?

Я видел следующий абзац в каком-то тесте по информатике, и я надеюсь, что смогу получить здесь хорошее объяснение того, что это значит, потому что я гуглил его в течение часа и ничего не могу найти..

"когда мы говорим, что язык Java имеет вызов виртуального метода мы имеем в виду, что в java-приложениях выполняемый метод определяется типом объекта во время выполнения"

Что это значит? кто-нибудь может объяснить это лучше?

4 ответов


автор этих строк использовал терминологию c++virtual.

лучшая терминология -динамическая привязка / динамическая отправка.

это означает, что динамический объект тип "выбирает", какой метод будет вызван, а не статический тип.

например: [псевдокод]:

class A {
  public void foo() { }
}
class B extends A { 
  public void foo() { }
}

при вызове:

A obj = new B();
obj.foo();

B.foo() будет вызываться, а не A.foo(), так как динамический тип из obj is B.


мы имеем в виду, что в java-приложениях выполняемый метод определяется типом объекта во время выполнения

interface Animal{
  public void eat();
}


class Person implements Animal{
   public void eat(){ System.out.println("Eating Food");}
}



class Eagle implements Animal{
   public void eat(){ System.out.println("Eating Snake");}
}

в основном

Animal animal = new Person();
animal.eat(); //it will print eating food
animal = new Eagle();
animal.eat(); //it will print eating snake

Предположим, у вас есть класс Fruit, с двумя подклассами Orange и Banana. И предположим, что у этого плода есть String getColor() метод.

оранжевый может переопределить getColor() метод для возврата "orange". То же самое для банана, который может вернуть "желтый".

когда какой-то метод использует объект типа Fruit и вызывает getColor() метод, метод, который будет называться Banana.getColor() если тип плода на самом деле банан.

 private void printColor(Fruit f) {
     System.out.println(f.getColor());
 }

 ...

 Fruit fruit1 = new Banana();
 Fruit fruit2 = new Orange();
 printColor(fruit1); // prints yellow
 printColor(fruit2); // prints orange     

сотрудник.java

public class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
}

VirtualMethod.java

class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       this.salary=salary;
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " 
       + " with salary " + salary);
   }

}

public class VirtualMethod
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

выход

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to  with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to  with salary 2400.0

объяснение

здесь мы создаем два Salary объекты. С помощью Salary ссылка s, а другой с помощью Employee ссылка e.

, а вызов s.mailCheck() компилятор видит mailCheck() на Salary класс во время компиляции и JVM вызывает mailCheck() на Salary класса во время выполнения.

вызов mailCheck() on e - это совсем другое, потому что e это Employee ссылка. Когда компилятор видит e.mailCheck() компилятор видит mailCheck() метод Employee класса.

здесь, во время компиляции, компилятор использовать mailCheck() на Employee для проверки этого утверждения. Однако во время выполнения JVM вызывает mailCheck() на Salary класса.