Что такое виртуальный метод вызова в 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 является 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() способ вернуть "апельсин". То же самое для банана, который может вернуть "желтый".

Когда какой-то метод использует объект типа 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     

Employee.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() на e совсем другой, потому что e является Employee ссылка. Когда компилятор видит e.mailCheck()компилятор видит mailCheck() метод в Employee учебный класс.

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

Другие вопросы по тегам