next up previous contents index
suivant: 4.6 Finalité monter: 4. Composition, abstraction, extension précédent: 4.4 Extension et héritage   Table des matières   Index


4.5 Liaison tardive

Le mécanisme de liaison est celui qui associe à un nom l'entité qu'il désigne. Cette association est déterminée d'une part par le texte du programme, notamment par la portée lexicale des noms dans les blocs, et d'autre part par l'environnement d'exécution. Dans la plupart des langages, et même en Java pour la plupart des noms (de variables, de fonctions), la liaison d'un nom est déterminée à la compilation : c'est une liaison statique. Dans certains cas, le sous-typage conduit à retarder cette liaison jusqu'à l'exécution : c'est la liason tardive. C'est ainsi qu'un nom déclaré d'un certain type peut désigner une instance d'un sous-type :

  Point 
    pc = new PointColore(2, 3, java.awt.Color.pink),
    pi = new PointImmobile(2, 3),
    p  = Math.random()>0.5 ? pc : pi;
  p.translater(1,1);

La troisième affectation est correcte, car de la forme « type = sous-type » : le type du nom p est Point, tandis que le type de la valeur affectée à p est PointColore ou PointImmobile. La méthode translater(double, double) de la classe Point est redéfinie dans la classe PointImmobile. L'évaluation de l'expression p.translater(1, 2) consiste à invoquer la méthode translater(double, double) définie dans la classe de l'objet désigné par p, soit celle de PointImmobile, soit celle de PointColore. La liaison du nom translater à l'une de ces méthodes ne peut être réalisée en général qu'à l'exécution, quand le type réel de p est connu. Il s'agit d'une liaison tardive, qui est une des particularités des langages orientés objets. Ce mécanisme est propre aux méthodes et ne s'applique pas aux champs ni aux fonctions.

On peut déclarer une variable ou un paramètre d'un type abstrait. Le mécanisme de liaison tardive permettra d'invoquer la méthode correcte une fois que la variable ou le paramètre désignera une instance d'une classe réalisant cette interface.


4.5.0.0.1 Spécialisation d'une classe par redéfinition

Une méthode n'est pas héritée si elle est redéfinie dans la classe dérivée, avec le même type de retour et le même profil. Par exemple, la classe PointImmobile suivante redéfinit la méthode translater de profil (double, double), de sorte qu'elle ne translate pas sa cible :

class PointImmobile extends Point {
  PointImmobile(double x, double y) {
    super(x, y);
  }
  void translater(double dx, double dy) {}
}

Le mécanisme d'extension permet à la fois d'enrichir une classe en lui ajoutant des membres, et de la spécialiser, par redéfinition de certaines méthodes, pour en modifier le comportement. Le mécanisme de liaison tardive permet de tirer parti de ces redéfinitions.

Signalons que la redéfinition d'une méthode peut invoquer la méthode de la classe parente à l'aide du nom super : employé dans une méthode, il réfère à l'objet auquel s'applique cette méthode, en tant qu'instance de la classe parente. Il permet ainsi d'accéder aux membres (champs ou méthodes) définis dans la classe parente, même s'ils sont masqués ou redéfinis dans la classe contenant cette utilisation de super ; ce serait le cas si nous avions redéfini translater ainsi :

  void translater(double dx, double dy) {
    super.translater(0, 0);
  }


4.5.0.0.2 Évaluation d'une invocation

En combinant différents mécanismes de Java (typage statique, résolution de la surcharge, liaison tardive), nous pouvons maintenant décrire les différentes étapes de l'invocation d'une méthode de la forme cible.m(arg$_1$, ...) :

  1. le type (classe ou interface) $t$ qui doit avoir une méthode m parmi ses membres est déterminé comme le type de l'expression cible (typage statique, le type de sa valeur n'intervient pas à cette étape) ;
  2. le type des expressions arguments détermine les méthodes candidates parmi les méthodes de nom m de $t$ ayant un profil compatible avec les types des arguments ;
  3. s'il y a plusieurs méthodes candidates, l'une d'entre-elles est sélectionnée comme étant la plus spécifique, si elle existe (résolution de la surcharge) ;
  4. l'évaluation de l'expression cible produit une référence à une instance d'une classe $C$ qui est nécessairement un sous-type de $t$ ;
  5. l'évaluation des arguments arg$_1$, ... produit des valeurs $v_1$,...(le type de ces valeurs n'intervient pas) ;
  6. la liaison tardive détermine la méthode qui sera invoquée comme étant la méthode sélectionnée si elle n'est pas redéfinie, ou sinon comme la redéfinition de la méthode sélectionnée qui est héritée par la classe $C$ ;
  7. un cadre d'invocation est créé ;
  8. les valeurs des arguments sont éventuellement converties en des valeurs du type des paramètres de la méthode déterminée par la liaison tardive et servent à initialiser les paramètres de la méthode.


4.5.0.0.3 Sous-typage

Voici enfin la définition de la relation de sous-typage :


next up previous contents index
suivant: 4.6 Finalité monter: 4. Composition, abstraction, extension précédent: 4.4 Extension et héritage   Table des matières   Index
Rene' LALEMENT 2001-11-07