L'exécution d'un programme Java nécessite deux étapes : la compilation et l'exécution (interprétation). En même temps, Java est un langage de programmation orienté objet. Lorsque la sous-classe et la classe parent ont la même méthode et que la sous-classe remplace la méthode de la classe parent, lorsque le programme appelle la méthode au moment de l'exécution, doit-il appeler la méthode de la classe parent ou la méthode substituée de la sous-classe ? devrait être la question lorsque nous apprenons pour la première fois les problèmes rencontrés en Java. Ici, nous allons d’abord déterminer quelle méthode appeler ou quelle opération de variables est appelée liaison.
Il existe deux méthodes de liaison en Java, l'une est la liaison statique, également appelée liaison anticipée. L’autre est la liaison dynamique, également appelée liaison tardive.
Le concept de liaison de programme :
La liaison fait référence à l'association d'un appel de méthode avec la classe (corps de la méthode) dans laquelle se trouve la méthode. Pour Java, la liaison est divisée en liaison statique et liaison dynamique ; ou liaison anticipée et liaison tardive
Liaison statique (liaison anticipée du compilateur) :
La méthode a été liée avant l'exécution du programme. , qui est implémenté par le compilateur ou un autre éditeur de liens. Par exemple : C. Pour Java, cela peut être compris comme une liaison lors de la compilation du programme ; en particulier, les seules méthodes en Java sont les méthodes finales, statiques, privées et constructeur, qui sont des liaisons précoces
liaison dynamique (liaison d'exécution de liaison tardive) ) :
Liaison tardive : liaison basée sur le type d'objet spécifique au moment de l'exécution.
Si un langage implémente une liaison tardive, il doit également fournir un mécanisme pour déterminer le type de l'objet pendant l'exécution et appeler respectivement les méthodes appropriées. En d'autres termes, le compilateur ne connaît toujours pas le type de l'objet pour le moment, mais le mécanisme d'appel de méthode peut enquêter par lui-même et trouver le corps de méthode correct. Différentes langues implémentent la liaison tardive différemment. Pensez-y de cette façon : ils doivent tous insérer un type spécial d’informations dans l’objet.
Processus de liaison dynamique :
La machine virtuelle extrait la table de méthodes du type réel de l'objet
La machine virtuelle recherche la signature de la méthode
Appelle la méthode
Résumé de la liaison :
Après avoir compris les concepts des trois, nous avons découvert que Java appartient à la liaison tardive. En Java, presque toutes les méthodes sont liées tardivement. Les méthodes liées dynamiquement appartiennent à des sous-classes ou à des classes de base au moment de l'exécution. Mais il y en a aussi des spéciales. Étant donné que les méthodes statiques et les méthodes finales ne peuvent pas être héritées, leurs valeurs peuvent être déterminées au moment de la compilation. Un point particulier à noter est que les méthodes et les variables membres déclarées en privé ne peuvent pas être héritées par les sous-classes. Toutes les méthodes privées sont implicitement désignées comme finales (de là, nous savons : déclarer les méthodes comme type final consiste à empêcher la méthode d'être écrasée. , la seconde est de désactiver efficacement la liaison dynamique en Java). La liaison tardive en Java est implémentée par la JVM. Nous n'avons pas besoin de la déclarer explicitement, mais c'est différent en C. Une certaine méthode doit être explicitement déclarée pour avoir une liaison tardive. La conversion ascendante ou le polymorphisme en Java est réalisé à l'aide de la liaison dynamique, donc comprendre la liaison dynamique signifie également la conversion ascendante et le polymorphisme.
Pour les méthodes en Java, à l'exception des méthodes finales, statiques, privées et constructeur qui sont pré-liées, toutes les autres méthodes sont liées dynamiquement. La liaison dynamique se produit généralement sous la déclaration de conversion de la classe parent et de la sous-classe :
Par exemple : Parent p = new Children();
Le processus spécifique est le suivant :
1. Le compilateur vérifie le type déclaré et le nom de méthode de l'objet. Supposons que nous appelions la méthode x.f(args) et que x ait été déclaré comme objet de classe C, alors le compilateur énumérera toutes les méthodes nommées f dans la classe C et les méthodes f héritées de la super classe de classe C
2. Ensuite, le compilateur vérifie les types de paramètres fournis dans l'appel de méthode. Si parmi toutes les méthodes nommées f, il existe un type de paramètre qui correspond le mieux au type de paramètre fourni par l'appel, alors cette méthode est appelée "résolution de surcharge"
Lorsque le programme est en cours d'exécution. et utilise dynamique Lorsqu'une liaison appelle une méthode, la machine virtuelle doit appeler une version de la méthode qui correspond au type réel de l'objet pointé par x. Supposons que le type réel soit D (une sous-classe de C). Si la classe D définit f(String), alors cette méthode est appelée, sinon la méthode f(String) est recherchée dans la superclasse de D, et ainsi de suite. 🎜>
Réflexion sur un problème : Comment fournir aux utilisateurs de la méthode une méthode pour accomplir une tâche. Que se passe-t-il si l’utilisateur a des exigences particulières et peut-il personnaliser sa propre méthode ? Connaissances impliquées : Classes enfants et parents, interfaces, transformation ascendante, liaison dynamique Code spécifique :package com.chengxuyuanzhilu; public interface MyInterfaces { void doting(); } package com.chengxuyuanzhilu; public class Drink implements MyInterfaces { @Override public void doting() { System.out.println("我在喝水"); } } package com.chengxuyuanzhilu; public class Eat implements MyInterfaces { @Override public void doting() { System.out.println("我在吃东西"); } } package com.chengxuyuanzhilu; public class Run implements MyInterfaces { @Override public void doting() { System.out.println("我在奔跑"); } } package com.chengxuyuanzhilu; public class TestDynamicBind { public static void main(String[] args) { MyInterfaces my = null; my = new Eat(); bind(my); my = new Drink(); bind(my); my = new Run(); bind(my); } static void bind(MyInterfaces my){ my.doting(); } }