Qu'est-ce que l'appel de méthode virtuelle en java?
J'ai vu le paragraphe suivant dans un test d'informatique et j'espère pouvoir obtenir ici une bonne explication de ce que cela signifie parce que je l'ai googlé pendant une heure et je ne trouve rien..
"Lorsque nous disons que le langage Java a appel de méthode virtuelle , nous voulons dire que dans les applications java, la méthode exécutée est déterminée par le type d'objet au moment de l'exécution"
Qu'est-ce que cela signifie? quelqu'un peut-il expliquer mieux?
4 answers
L'auteur de ces lignes a utilisé la terminologie c++ de virtual
.
Une meilleure terminologie est liaison dynamique / distribution dynamique.
Cela signifie que le type dynamique de l'objet "choisit" la méthode qui sera invoquée, et non le type statique.
Par exemple: [pseudo code]:
class A {
public void foo() { }
}
class B extends A {
public void foo() { }
}
Lors de l'appel:
A obj = new B();
obj.foo();
B.foo()
sera invoqué, et PAS A.foo()
, puisque le type dynamique de obj
est B
.
Nous voulons dire que dans les applications java, la méthode exécutée est déterminée par le type d'objet au moment de l'exécution
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");}
}
Dans main
Animal animal = new Person();
animal.eat(); //it will print eating food
animal = new Eagle();
animal.eat(); //it will print eating snake
Supposons que vous ayez une classe Fruit, avec deux sous-classes Orange et Banana. Et supposons que Fruit ait une méthode String getColor()
.
Orange peut remplacer la méthode getColor()
pour renvoyer "orange". Même chose pour la banane, qui peut le faire retourner "jaune".
Quand une méthode utilise un objet de type Fruit, et appelle la méthode getColor()
, la méthode qui sera appelée est Banana.getColor()
si le type du Fruit est en fait une banane.
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
De l'Employé.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);
}
}
Méthode virtuelle.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();
}
}
Sortie
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
Explication
Ici, nous instancions deux Salary
objets. L'un utilisant une référence Salary
s
, et l'autre utilisant une référence Employee
e
.
, Tout en invoquant s.mailCheck()
le compilateur voit mailCheck()
dans le Salary
classe au moment de la compilation, et la JVM appelle mailCheck()
dans le Salary
classe au moment de l'exécution.
Invoquant mailCheck()
sur e
est tout à fait différent car e
est une référence Employee
. Lorsque le compilateur voit e.mailCheck()
, le compilateur voit le mailCheck()
méthode dans le Employee
classe.
Ici, au moment de la compilation, le compilateur utilisé mailCheck()
dans Employee
pour valider cette affirmation. Au moment de l'exécution, cependant, la JVM appelle mailCheck()
dans la classe Salary
.