What is virtual method calling in java?

Solution 1:

The author of these lines used the c++ terminology of virtual.

A better terminology is dynamic binding / dynamic dispatch.

That means, that the object's dynamic type is "chosing" which method will be invoked, and not the static type.

For example: [pseudo code]:

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

when invoking:

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

B.foo() will be invoked, and NOT A.foo(), since the dynamic type of obj is B.

Solution 2:

we mean that in java applications the executed method is determined by the object type in run time

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");}
}

in main

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

Solution 3:

Suppose you have a class Fruit, with two subclasses Orange and Banana. And suppose that Fruit has a String getColor() method.

Orange can override the getColor() method to return "orange". Same for Banana, which can have it return "yellow".

When some method uses an object of type Fruit, and call the getColor() method, the method that will be called is Banana.getColor() if the type of the Fruit is in fact Banana.

 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     

Solution 4:

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();
    }
}

Output

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

Explanation

here, we instantiate two Salary objects. One using a Salary reference s, and the other using an Employee reference e.

While invoking s.mailCheck() the compiler sees mailCheck() in the Salary class at compile time, and the JVM invokes mailCheck() in the Salary class at run time.

Invoking mailCheck() on e is quite different because e is an Employee reference. When the compiler sees e.mailCheck(), the compiler sees the mailCheck() method in the Employee class.

Here, at compile time, the compiler used mailCheck() in Employee to validate this statement. At run time, however, the JVM invokes mailCheck() in the Salary class.