Что такое виртуальный метод вызова в Java? - PullRequest
17 голосов
/ 26 февраля 2012

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

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

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

Ответы [ 4 ]

33 голосов
/ 26 февраля 2012

Автор этих строк использовал терминологию 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.

13 голосов
/ 26 февраля 2012

мы имеем в виду, что в 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
4 голосов
/ 26 февраля 2012

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

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

Когда какой-либо метод использует объект типа 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     
1 голос
/ 05 июня 2015

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...