web-dev-qa-db-fra.com

Quelle est la différence entre le polymorphisme dynamique et statique en Java?

Quelqu'un peut-il fournir un exemple simple expliquant la différence entre dynamique et statique polymorphisme en Java?

92
Prabhakar Manthena

Polymorphisme

1. Liaison statique/Liaison au moment de la compilation/Liaison anticipée/Surcharge de méthode. (Dans la même classe)

2. Liaison dynamique/Liaison au moment de l'exécution/Liaison tardive/Méthode surchargée (dans différentes classes)

exemple de surcharge:

class Calculation {  
  void sum(int a,int b){System.out.println(a+b);}  
  void sum(int a,int b,int c){System.out.println(a+b+c);}  

  public static void main(String args[]) {  
    Calculation obj=new Calculation();  
    obj.sum(10,10,10);  // 30
    obj.sum(20,20);     //40 
  }  
}  

exemple prépondérant:

class Animal {    
   public void move(){
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {

   public void move() {
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal(); // Animal reference and object
      Animal b = new Dog(); // Animal reference but Dog object

      a.move();//output: Animals can move

      b.move();//output:Dogs can walk and run
   }
}
156
KhAn SaAb
  • La surcharge de méthode serait un exemple de polymorphisme statique

  • alors que le dépassement serait un exemple de polymorphisme dynamique.

    Parce que, en cas de surcharge, le compilateur sait à la compilation quelle méthode lier à l'appel. Cependant, il est déterminé au moment de l'exécution pour le polymorphisme dynamique

26
user1374

Polymorphisme dynamique (à l'exécution) est le polymorphisme existant au moment de l'exécution. Ici, le compilateur Java ne comprend pas quelle méthode est appelée au moment de la compilation. Seule la machine virtuelle Java décide quelle méthode est appelée au moment de l'exécution. La surcharge de méthodes et le remplacement de méthodes à l'aide de méthodes d'instance sont des exemples de polymorphisme dynamique.

Par exemple,

  • Prenons une application qui sérialise et désérialise différents types de documents

  • Nous pouvons avoir ‘Document’ comme classe de base et différents types de documents Classes qui en dérivent. Par exemple. XMLDocument, WordDocument, etc.

  • La classe de document définira les méthodes ‘Serialize ()» et 'De-serialize () »comme étant virtuelles et chaque classe dérivée implémentera ces méthodes À sa manière, en fonction du contenu réel des documents.

  • Lorsque différents types de documents doivent être sérialisés/désérialisés, les objets de document sont référencés par La "référence de classe" du document (ou pointeur) et lorsque " Serialize ()" ou " La méthode De-serialize () est appelée, les versions appropriées des méthodes virtuelles sont appelées.

Polymorphisme statique (au moment de la compilation) est le polymorphisme présenté au moment de la compilation. Ici, le compilateur Java sait quelle méthode est appelée. Surcharge de méthode et substitution de méthode à l'aide de méthodes statiques; méthode surchargée à l'aide de méthodes privées ou finales sont des exemples de polymorphisme statique

Par exemple,

  • Un objet employee peut avoir deux méthodes print (), l'une prenant n ° arguments et l'autre prenant une chaîne de préfixe à afficher avec Les données d'employé.

  • Étant donné ces interfaces, lorsque la méthode print () est appelée sans aucun argument , Le compilateur examine les arguments de la fonction et sait quelle fonction doit être appelée et génère le code de l'objet .__ en conséquence.

Pour plus de détails, veuillez lire "Qu'est-ce que le polymorphisme" (Google).

12
rachana

La liaison fait référence au lien entre l'appel de méthode et la définition de méthode.

Cette image montre clairement ce qui est contraignant.

 binding

Dans cette image, l'appel “a1.methodOne ()” est lié à la définition correspondante de methodOne () et l'appel “a1.methodTwo ()” est lié à la définition correspondante de methodTwo ().

Pour chaque appel de méthode, il doit exister une définition de méthode appropriée. C'est une règle en Java. Si le compilateur ne voit pas la définition de méthode appropriée pour chaque appel de méthode, il génère une erreur.

Passons maintenant à la liaison statique et à la liaison dynamique en Java.

Liaison statique en Java:

La liaison statique est une liaison qui se produit lors de la compilation. Il est également appelée liaison anticipée car la liaison a lieu avant un programme fonctionne réellement

.

La liaison statique peut être démontrée comme dans l'image ci-dessous.

 enter image description here

Dans cette image, «a1» est une variable de référence de type classe A pointant vers un objet de classe A. «a2» est également une variable de référence de type classe A mais pointant vers un objet de classe B.

Lors de la compilation, lors de la liaison, le compilateur ne vérifie pas le type d'objet sur lequel une variable de référence particulière pointe. Il vérifie simplement le type de variable de référence à travers lequel une méthode est appelée et vérifie s'il existe une définition de méthode pour ce type.

Par exemple, pour l’appel à la méthode «a1.method ()» dans l’image ci-dessus, le compilateur vérifie s’il existe une définition de méthode pour method () dans la classe A. Parce que «a1» correspond au type de classe A. De même, pour l’appel de méthode «a2.method ()», il vérifie s’il existe une définition de méthode pour method () dans la classe A. Etant donné que «a2» correspond également à un type de classe A. Il ne vérifie pas vers quel objet, «a1» et «a2» pointent. Ce type de liaison est appelé liaison statique.

Liaison dynamique en Java:

La liaison dynamique est une liaison qui se produit pendant l'exécution. C'est aussi appelé liaison tardive car la liaison se produit lorsque le programme est réellement fonctionnement.

Pendant l'exécution, les objets réels sont utilisés pour la liaison. Par exemple, pour l’appel «a1.method ()» dans l’image ci-dessus, la méthode () de l’objet réel pointé par «a1» sera appelée. Pour l’appel “a2.method ()”, la méthode () de l’objet réel pointé par “a2” sera appelée. Ce type de liaison est appelé liaison dynamique.

La liaison dynamique de l'exemple ci-dessus peut être démontrée comme ci-dessous.

 enter image description here

Référence static-binding-and-dynamic-binding-in-Java

10
Elsayed

Polymorphisme: Le polymorphisme est la capacité d'un objet à prendre de nombreuses formes. L'utilisation la plus courante du polymorphisme dans OOP se produit lorsqu'une référence de classe parent est utilisée pour faire référence à un objet de classe enfant.

Liaison dynamique/Polymorphisme à l'exécution:

Polymorphisme d'exécution également connu sous le nom de méthode prioritaire. Dans ce mécanisme par lequel un appel à une fonction remplacée est résolu au moment de l'exécution.

public class DynamicBindingTest {

    public static void main(String args[]) {
        Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
        vehicle.start();       //Car's start called because start() is overridden method
    }
}

class Vehicle {

    public void start() {
        System.out.println("Inside start method of Vehicle");
    }
}

class Car extends Vehicle {

    @Override
    public void start() {
        System.out.println("Inside start method of Car");
    }
}

Sortie:

Méthode de démarrage intérieur de voiture

Liaison statique/polymorphisme à la compilation:

La méthode à appeler est décidée au moment de la compilation uniquement.

public class StaticBindingTest {

    public static void main(String args[])  {
       Collection c = new HashSet();
       StaticBindingTest et = new StaticBindingTest();
       et.sort(c);

    }

    //overloaded method takes Collection argument
    public Collection sort(Collection c){
        System.out.println("Inside Collection sort method");
        return c;
    }


   //another overloaded method which takes HashSet argument which is sub class
    public Collection sort(HashSet hs){
        System.out.println("Inside HashSet sort method");
        return hs;
    }

}

Résultat: Inside Collection sort metho

7
loknath

method overloading est un exemple de polymorphisme statique/à la compilation car la liaison de méthode entre appel de méthode et définition de méthode se produit au moment de la compilation et dépend de la référence de la classe (référence créée lors de la compilation et empilée).

method overriding est un exemple de polymorphisme dynamique/d'exécution, car la liaison de méthode entre appel de méthode et définition de méthode se produit au moment de l'exécution et dépend de l'objet de la classe (objet créé à l'exécution et va au tas).

7
Sujith PS

En termes simples: 

Polymorphisme statique: le même nom de méthode est surchargé avec un type ou un nombre différent de paramètres dans même classe (différent Signature). L'appel à une méthode ciblée est résolu au moment de la compilation. 

Polymorphisme dynamique} _: la même méthode est remplacée avec la même signature dans classes différentes. Le type d'objet sur lequel la méthode est appelée n'est pas connu au moment de la compilation mais sera décidé au moment de l'exécution.

Généralement, la surcharge ne sera pas considérée comme un polymorphisme. 

De Java tutorial page :

Les sous-classes d'une classe peuvent définir leurs propres comportements tout en partageant certaines des mêmes fonctionnalités de la classe parente

6
Ravindra babu

Polymorphisme statique: est l'endroit où la décision de résoudre la méthode à accomplir est déterminée pendant le temps de compilation. La surcharge de méthode pourrait en être un exemple.

Polymorphisme dynamique: est l'endroit où la décision de choisir la méthode à exécuter est définie pendant l'exécution. Méthode Overriding pourrait en être un exemple.

3
Kulasangar

Le polymorphisme fait référence à la capacité d'un objet à se comporter différemment pour le même déclencheur.

Polymorphisme statique (polymorphisme au moment de la compilation)

  • Le polymorphisme statique détermine la méthode à exécuter pendant la compilation Time.
  • La surcharge de méthode est un exemple de polymorphisme statique, et elle est requise pour se produire.
  • Polymorphisme statique obtenu par liaison statique.
  • Le polymorphisme statique se produit dans la même classe.
  • L'attribution d'objet n'est pas requise pour le polymorphisme statique.
  • Héritage non impliqué pour le polymorphisme statique.

Polymorphisme dynamique (polymorphisme à l'exécution)

  • Le polymorphisme dynamique détermine la méthode à exécuter au moment de l'exécution.
  • Le dépassement de méthode est un exemple de polymorphisme dynamique, et il est requis pour que le polymorphisme dynamique se produise.
  • Polymorphisme dynamique obtenu par liaison dynamique.
  • Le polymorphisme dynamique se produit entre différentes classes.
  • Il est requis lorsqu'un objet de sous-classe est affecté à un objet super class Pour le polymorphisme dynamique.
  • Héritage impliqué pour le polymorphisme dynamique.
2

Method Overloading est connu sous le nom de Static Polymorphism et est également connu sous le nom de Compile Time Polymorphism ou Static Binding car les appels de méthode surchargés sont résolus au moment de la compilation par le compilateur sur la base du liste d'arguments et la référence sur laquelle nous appelons la méthode.

Et Method Overriding est appelé Polymorphism Dynamique ou simple Polymorphism ou Runtime Method Dispatch ou Dynamic Binding car l'appel de méthode surchargé est résolu au moment de l'exécution.

Afin de comprendre pourquoi il en est ainsi, prenons un exemple de Mammal et Human class

class Mammal {
    public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); }
}

class Human extends Mammal {

    @Override
    public void speak() { System.out.println("Hello"); }

    public void speak(String language) {
        if (language.equals("Hindi")) System.out.println("Namaste");
        else System.out.println("Hello");
    }

}

J'ai inclus la sortie ainsi que le bytecode dans les lignes de code ci-dessous

Mammal anyMammal = new Mammal();
anyMammal.speak();  // Output - ohlllalalalalalaoaoaoa
// 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V

Mammal humanMammal = new Human();
humanMammal.speak(); // Output - Hello
// 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V

Human human = new Human();
human.speak(); // Output - Hello
// 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V

human.speak("Hindi"); // Output - Namaste
// 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V

Et en regardant le code ci-dessus, nous pouvons voir que les bytecodes de humanMammal.speak (), human.speak () et human.speak ("Hindi") sont totalement différents car le compilateur est capable de les différencier en fonction de la liste d'arguments et référence de classe. Et c’est pourquoi la méthode Method Overloading est appelée Polymorphism statique.

Mais le bytecode pour anyMammal.speak () et humanMammal.speak () est identique car, selon le compilateur, les deux méthodes sont appelées sur une référence Mammal, mais la sortie des deux appels de méthode est différente car à l'exécution, la machine virtuelle Java sait quel objet une référence détient et les appels de machine virtuelle la méthode sur l’objet et c’est pourquoi la méthode Priorité est connue sous le nom de polymorphisme dynamique.

Ainsi, à partir du code et du bytecode ci-dessus, il est clair que lors de la phase de compilation, la méthode d’appel est considérée à partir du type de référence. Mais au moment de l'exécution, la méthode sera appelée à partir de l'objet que la référence contient.

Si vous voulez en savoir plus à ce sujet, vous pouvez en lire plus sur Comment la machine virtuelle Java gère-t-elle la surcharge et la substitution de méthodes en interne .

2
Naresh Joshi

Considérons le code ci-dessous:

public class X
{
    public void methodA() // Base class method
    {
        System.out.println ("hello, I'm methodA of class X");
    }
}

public class Y extends X
{
    public void methodA() // Derived Class method
    {
        System.out.println ("hello, I'm methodA of class Y");
    }
}
public class Z
{
public static void main (String args []) {

    //this takes input from the user during runtime
    System.out.println("Enter x or y");
    Scanner scanner = new Scanner(System.in);
    String value= scanner.nextLine();

    X obj1 = null;
    if(value.equals("x"))
        obj1 = new X(); // Reference and object X
    else if(value.equals("y"))
        obj2 = new Y(); // X reference but Y object
    else
        System.out.println("Invalid param value");

    obj1.methodA();
}
}

Maintenant, en regardant le code, vous ne pouvez jamais savoir quelle implémentation de methodA () sera exécutée, car cela dépend de la valeur donnée par l'utilisateur lors de l'exécution. Ainsi, il est uniquement décidé lors de l'exécution de quelle méthode sera appelée. Par conséquent, le polymorphisme d'exécution.

1
user2048204

Polymorphisme au moment de la compilation (Liaison statique/Liaison précoce): Dans le polymorphisme statique, si nous appelons une méthode dans notre code, la définition de cette méthode à appeler est résolue au moment de la compilation uniquement.

(ou)

Lors de la compilation, Java sait quelle méthode invoquer en vérifiant les signatures de la méthode. C'est ce qu'on appelle un polymorphisme au moment de la compilation ou une liaison statique.

Polymorphisme dynamique (liaison tardive/polymorphisme à l'exécution): Au moment de l'exécution, Java attend le moment de l'exécution pour déterminer quel objet est réellement pointé par la référence. La résolution de la méthode a été prise au moment de l'exécution, c'est pourquoi nous appelons polymorphisme d'exécution.

1
Pavan Reddy

La surcharge de méthode est un polymorphisme de compilation, prenons un exemple pour comprendre le concept.

class Person                                            //person.Java file
{
    public static void main ( String[] args )
    {
      Eat e = new Eat();
       e.eat(noodle);                                //line 6
    }

   void eat (Noodles n)      //Noodles is a object    line 8                     
   {

   }
   void eat ( Pizza p)           //Pizza is a object
  {

  }

}

Dans cet exemple, Person utilise une méthode de restauration qui signifie qu’elle peut manger de la pizza ou des nouilles. Que la méthode eat soit surchargée lorsque nous compilons ce Person.Java, le compilateur résout l'appel de méthode "e.eat (noodles) [qui est à la ligne 6] avec la définition de méthode spécifiée à la ligne 8, méthode qui prend noodles en paramètre et le processus entier est effectué par le compilateur, il s'agit donc du temps de compilation Polymorphism . Le processus de remplacement de l'appel de méthode par la définition de méthode est appelé liaison, dans ce cas, il est effectué par le compilateur et appelé dès que possible. contraignant.

0
Manoj Gururaj