Quelqu'un peut-il fournir un exemple simple qui explique la différence entre le polymorphisme dynamique et statique en Java?
java
oop
polymorphism
overloading
overriding
Prabhakar Manthena
la source
la source
Réponses:
Polymorphisme
1. Liaison statique / liaison à la compilation / liaison anticipée / surcharge de méthode (dans la même classe)
2. Liaison dynamique / Liaison d'exécution / Liaison tardive / Remplacement de méthode (dans différentes classes)
exemple de surcharge:
exemple primordial:
la source
Animal reference but Dog object
, pourquoi ne pouvons-nous pas utiliserDog reference and dog object
?La surcharge de méthode serait un exemple de polymorphisme statique
alors que le dépassement serait un exemple de polymorphisme dynamique.
Car, en cas de surcharge, au moment de la compilation, le compilateur sait quelle méthode lier à l'appel. Cependant, il est déterminé à l'exécution pour le polymorphisme dynamique
la source
Le polymorphisme dynamique (à l'exécution) est le polymorphisme qui existait à l'exécution. Ici, le compilateur Java ne comprend pas quelle méthode est appelée au moment de la compilation. Seule la JVM décide quelle méthode est appelée au moment de l'exécution. La surcharge de méthode et le remplacement de méthode à l'aide de méthodes d'instance sont des exemples de polymorphisme dynamique.
Par exemple,
Considérez une application qui sérialise et désérialise différents types de documents.
Nous pouvons avoir 'Document' comme classe de base et différentes classes de type de document qui en dérivent. Par exemple, XMLDocument, WordDocument, etc.
La classe de document définira les méthodes «Serialize ()» et «De-serialize ()» comme 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 seront référencés par la référence de classe 'Document' (ou pointeur) et lorsque la méthode 'Serialize ()' ou 'De-serialize ()' est appelée dessus, les versions appropriées des méthodes virtuelles sont appelées.
Le 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 remplacement de méthode à l'aide de méthodes statiques; le remplacement de méthode à l'aide de méthodes privées ou finales sont des exemples de polymorphisme statique
Par exemple,
Un objet employé peut avoir deux méthodes print (), l'une ne prenant aucun argument et l'autre prenant une chaîne de préfixe à afficher avec les données de l'employé.
Étant donné ces interfaces, lorsque la méthode print () est appelée sans aucun argument, le compilateur, en regardant les arguments de la fonction, sait quelle fonction est censée être appelée et génère le code objet en conséquence.
Pour plus de détails, veuillez lire "Qu'est-ce que le polymorphisme" (Google it).
la source
Cette image montre clairement ce qui est contraignant.
Dans cette image, l'appel «a1.methodOne ()» est lié à la définition de methodOne () correspondante et l'appel «a1.methodTwo ()» est lié à la définition de methodTwo () correspondante.
Pour chaque appel de méthode, il doit y avoir 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 renvoie une erreur.
Maintenant, venez à la liaison statique et à la liaison dynamique en java.
Liaison statique en Java:
.
La liaison statique peut être démontrée comme dans l'image ci-dessous.
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.
Pendant la compilation, lors de la liaison, le compilateur ne vérifie pas le type d'objet vers lequel pointe une variable de référence particulière. Il vérifie simplement le type de variable de référence via laquelle une méthode est appelée et vérifie s'il existe une définition de méthode pour elle dans ce type.
Par exemple, pour l'appel de 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' est de type 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. Parce que 'a2' est également de type 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:
Pendant l'exécution, des 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 vers lequel pointe «a1» sera appelée. Pour l'appel «a2.method ()», la méthode () de l'objet réel vers lequel pointe «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.
Référence static-binding-and-dynamic-binding-in-java
la source
Polymorphisme: Le polymorphisme est la capacité d'un objet à prendre de nombreuses formes. L'utilisation la plus courante du polymorphisme dans la POO 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 d'exécution:
Polymorphisme à l'exécution, également appelé remplacement de méthode. Dans ce mécanisme par lequel un appel à une fonction remplacée est résolu au moment de l'exécution.
Production:
Méthode de démarrage intérieur de la voiture
Liaison statique / polymorphisme à la compilation:
La méthode à appeler est décidée au moment de la compilation uniquement.
Sortie: Metho de tri à l'intérieur de la collection
la source
la surcharge de méthode est un exemple de polymorphisme statique au moment de la compilation car la liaison de méthode entre l'appel de méthode et la 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 au moment de la compilation et va à la pile).
le remplacement de méthode est un exemple de polymorphisme dynamique à l'exécution, car la liaison de méthode entre l'appel de méthode et la définition de méthode se produit au moment de l'exécution et dépend de l'objet de la classe (objet créé au moment de l'exécution et va au tas).
la source
En termes simples:
Polymorphisme statique : le même nom de méthode est surchargé avec un type ou un nombre de paramètres différents dans la même classe (signature différente). L'appel de méthode ciblée est résolu au moment de la compilation.
Polymorphisme dynamique : la même méthode est remplacée par la même signature dans différentes classes . 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.
En général, la surcharge ne sera pas considérée comme un polymorphisme.
À partir de la page du didacticiel Java :
la source
Generally overloading won't be considered as polymorphism.
pouvez-vous s'il vous plaît élaborer sur ce point.La surcharge de méthode est connue sous le nom de polymorphisme statique et également connue sous le nom de polymorphisme au moment de la compilation ou de liaison statique car les appels de méthode surchargés sont résolus au moment de la compilation par le compilateur sur la base de la liste d'arguments et de la référence sur laquelle nous appelons la méthode.
Et méthode redéfinie est connu comme dynamique Polymorphisme simple ou Polymorphisme ou d' exécution Méthode de répartition ou de liaison dynamique parce que l' appel de méthode surchargée se résoudre à l' exécution.
Afin de comprendre pourquoi il en est ainsi, prenons un exemple de
Mammal
etHuman
classeJ'ai inclus la sortie ainsi que le bytecode dans les lignes de code ci-dessous
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 surcharge de méthode est connue sous le nom de polymorphisme statique .
Mais le bytecode pour anyMammal.speak () et humanMammal.speak () est le même car, selon le compilateur, les deux méthodes sont appelées sur la référence Mammal, mais la sortie des deux appels de méthode est différente car au moment de l'exécution, la JVM sait quel objet une référence contient et les appels JVM. la méthode sur l'objet et c'est pourquoi le remplacement de méthode est connu sous le nom de polymorphisme dynamique.
Ainsi, à partir du code et du bytecode ci-dessus, il est clair que pendant 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 contient la référence.
Si vous voulez en savoir plus à ce sujet, vous pouvez en savoir plus sur la manière dont la JVM gère la surcharge et le remplacement de méthode en interne .
la source
Polymorphisme statique: c'est là que la décision de résoudre la méthode à accomplir est déterminée pendant la compilation. La surcharge de méthode pourrait en être un exemple.
Polymorphisme dynamique: c'est là que la décision de choisir la méthode à exécuter est définie pendant l'exécution. Le remplacement de méthode pourrait en être un exemple.
la source
Le polymorphisme fait référence à la capacité d'un objet à se comporter différemment pour le même déclencheur.
Polymorphisme statique (polymorphisme à la compilation)
Polymorphisme dynamique (polymorphisme d'exécution)
la source
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 qui doit être appelée est résolue au moment de la compilation uniquement.
(ou)
Au moment de la compilation, Java sait quelle méthode appeler en vérifiant les signatures de méthode. Donc, cela s'appelle le polymorphisme à la compilation ou la liaison statique.
Polymorphisme dynamique (Late Binding / Runtime Polymorphism): Au moment de l'exécution, Java attend 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 le polymorphisme d'exécution.
la source
Considérez le code ci-dessous:
Maintenant, en regardant le code, vous ne pouvez jamais dire quelle implémentation de methodA () sera exécutée, car cela dépend de la valeur que l'utilisateur donne pendant l'exécution. Ainsi, il n'est décidé que pendant l'exécution de la méthode qui sera appelée. Par conséquent, le polymorphisme d'exécution.
la source
La surcharge de méthode est un polymorphisme au moment de la compilation, prenons un exemple pour comprendre le concept.
Dans cet exemple, Person a une méthode eat qui signifie qu'il peut manger de la pizza ou des nouilles. Que la méthode eat est 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, c'est-à-dire la méthode qui prend les noodles comme paramètre et le processus entier est fait par le compilateur donc c'est Polymorphisme au moment de la compilation. Le processus de remplacement de l'appel de méthode par la définition de méthode est appelé comme liaison, dans ce cas, il est fait par le compilateur donc il est appelé comme liaison précoce.
la source
Suite à la réponse de Naresh, le polymorphisme dynamique n'est «dynamique» qu'en Java en raison de la présence de la machine virtuelle et de sa capacité à interpréter le code au moment de l'exécution plutôt que le code s'exécutant en natif.
En C ++, il doit être résolu au moment de la compilation s'il est compilé dans un binaire natif en utilisant gcc, évidemment; cependant, le saut et le bruit à l'exécution dans la table virtuelle sont toujours appelés «recherche» ou «dynamique». Si C hérite de B, et que vous déclarez
B* b = new C(); b->method1();
, b sera résolu par le compilateur pour pointer vers un objet B à l'intérieur de C (pour une classe simple hérite d'une situation de classe, l'objet B à l'intérieur de C et C démarrera à la même adresse mémoire donc rien doit être fait; il pointera vers le vptr qu'ils utilisent tous les deux). Si C hérite de B et A, la table des fonctions virtuelles de l'objet A à l'intérieur de l'entrée C pour method1 aura un thunk qui décalera le pointeur vers le début de l'objet C encapsulant puis le passera au réel A :: method1 () dans le segment de texte que C a remplacé. PourC* c = new C(); c->method1()
, c pointera déjà vers l'objet C externe et le pointeur sera passé à C :: method1 () dans le segment de texte. Reportez-vous à: http://www.programmersought.com/article/2572545946/En java, pour
B b = new C(); b.method1();
, la machine virtuelle est capable de vérifier dynamiquement le type de l'objet associé à b et peut passer le bon pointeur et appeler la bonne méthode. L'étape supplémentaire de la machine virtuelle élimine le besoin de tables de fonctions virtuelles ou du type en cours de résolution au moment de la compilation, même s'il pouvait être connu au moment de la compilation. C'est juste une façon différente de le faire, ce qui a du sens lorsqu'une machine virtuelle est impliquée et que le code n'est compilé qu'en bytecode.la source