Je suis vraiment confus au sujet de la liaison dynamique et de la liaison statique. J'ai lu que déterminer le type d'un objet au moment de la compilation s'appelle une liaison statique et le déterminer lors de l'exécution est appelé une liaison dynamique.
Que se passe-t-il dans le code ci-dessous:
Liaison statique ou liaison dynamique?
Quel type de polymorphisme cela montre-t-il?
class Animal
{
void eat()
{
System.out.println("Animal is eating");
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog is eating");
}
}
public static void main(String args[])
{
Animal a=new Animal();
a.eat();
}
Votre exemple est liaison dynamique, car au moment de l'exécution, il est déterminé quel est le type de a
et la méthode appropriée est appelée.
Supposons maintenant que vous disposez également des deux méthodes suivantes:
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
Même si vous changez votre main
en
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
cela imprimera Animal is eating
, car l'appel à callEat
utilise liaison statique, et le compilateur sait seulement que a
est de type Animal
.
Cela dépend vraiment de surcharge et surcharge si vous avez fait quelque chose comme ça:
public class Animal{}
public class Dog extends Animal{}
public class AnimalActivity{
public void eat(Animal a){
System.out.println("Animal is eating");
}
public void eat(Dog d){
System.out.println("Dog is eating");
}
}
puis dans la classe principale:
public static void main(String args[])
{
Animal a=new Animal();
Animal d=new Dog();
AnimalActivity aa=new AnimalActivity();
aa.eat(a);
aa.eat(d);
}
le résultat dans les deux cas sera: Animal is eating
mais permet de le tordre, permet d'avoir ceci:
public class Animal{
public void eat(){
System.out.println("Animal is eating");
}
}
ensuite:
public class Dog extends Animal{
public void eat(){
System.out.println("Dog is eating");
}
}
puis dans la classe principale:
public static void main(String args[]){
Animal d=new Dog();
Animal a=new Animal();
a.eat();
d.eat();
}
maintenant le résultat devrait être:
Animal is eating
Dog is eating
cela est dû au fait que la surcharge des liaisons au moment de la compilation "liaison statique" tout en remplaçant les liaisons au moment de l'exécution "liaison dynamique"
Votre code actuel affichera Animal is eating
Cependant, dans votre classe principale, si vous avez créé un objet de type Dog
et que vous l'avez affecté à Animal
, votre sortie sera Dog is eating
En raison de la liaison dynamique.
public static void main(String args[])
{
Animal a = new Dog(); // An object of Dog is assigned to Animal
a.eat(); // Dynamically determines which eat() method to call
}
Même si a
est déclaré comme Animal
, il pointe vers un objet de type Dog
. Ainsi, à l'exécution, le type d'objet est déterminé et la méthode eat()
appropriée est appelée.
Une façon de penser est que method overloading
Est lié statiquement et method overriding
Est lié dynamiquement.
Pour les fonctions non statiques, vous utilisez une liaison statique chaque fois que la fonction n'est pas virtuelle, c'est-à-dire que le mot clé final
lui est appliqué et/ou que la fonction est private
. final
implique que la fonction ne peut pas être modifiée et le mot clé private
implique qu'elle n'a qu'une portée de classe. Sinon, la liaison dynamique est utilisée.
Pour les fonctions statiques, la liaison statique est toujours utilisée. Si un type A
est passé, il exécutera la méthode de A
, indépendamment de l'endroit où A
fait référence.
vérifier que cette classe d'employés a une fonction abstraite earning()
et que chaque classe a une implémentation de toString()
différente
Employee[] employees = new Employee[4];
// initialize array with Employees
employees[0] = new SalariedEmployee();
employees[1] = new HourlyEmployee();
employees[2] = new CommissionEmployee();
employees[3] = new BasePlusCommissionEmployee();
for (Employee currentEmployee : employees){
System.out.println(currentEmployee); // invokes toString
System.out.printf("earned $%,.2f%n", currentEmployee.earnings());
}
Tous les appels à la méthode toString
et earnings
sont résolus à execution time
, basé sur type of the object
auquel se réfère CurrentEmployee,
Ce processus est appelé dynamic binding
ou late binding
référence: Java ™ How To Program (Early Objects), Tenth Edition
Cas 1:
Animal a =new Animal();
a.eat();
Cas 2:
Animal a=new Dog();
a.eat();
Ici, les deux sont des liaisons dynamiques car pendant la compilation, le type de l'objet est déterminé, mais au moment de l'exécution en fonction de l'instance, l'objet auquel est affectée la méthode eat correspondante serait lié dynamiquement par la JVM.
Dans le premier cas, la méthode manger de la classe animale est appelée tandis que dans le second, la classe chien manger est appelée car l'objet Animal se voit attribuer une instance de chien. L'instance de Dog est également une instance d'animal. C'est-à-dire que vous pouvez le prendre car " est une relation " un chien est un animal. Donc ici le type d'objet est déterminé comme chien à l'exécution et JVM lie dynamiquement la méthode eat de la classe des chiens.
Vérifiez également ces liens
http://www.javatpoint.com/static-binding-and-dynamic-binding
http://www.coderanch.com/t/386124/Java/java/Static-Binding-Dynamic-Binding