next up previous
Next: Liaison tardive et représentation Up: Liaison tardive Previous: Polymorphisme et liaison tardive

Utilisation de Self

Rappelons le code des classes cell et backupCell

class cell =
 object(self)
     val mutable cont = 0
     method get  = cont
     method set n = cont <- n 
     method double = self#set (cont*2) 
     method print  = print_int self#get
 end;;

class backupCell =
 object
    inherit cell as super
    val mutable backup = 0
    method  set n = backup <- cont; super#set n;
    method print = print_string "Actual value: ";
                   super#print; print_newline();
                   print_string "Backup value: ";
                   print_int backup; print_newline()
    method restore = cont <- backup
end;;

let c = new cell;;

let bc = new backupCell;;

 bc#set(1);;
- : unit = ()

 bc#print;;
Actual value: 1
Backup value: 0
- : unit = ()

bc#double;;

Quel est le comportément de l'invocation bc#double?

bc#double => invocation de la methode double de cell
          => self#set(cont*2) 
          => invocation de quelle methode set?

L'objet référencé par self est l'objet courant. Mais qui est cet objet là? Clairement, au moment où le code self#set(cont*2) est écrit, il n'y a pas d'objet encore lié à self. Cette liaison ne peut être établie que de manière dynamique. Dans notre cas, l'objet courant (le dernier activé par un envoi de messages) est bc. Nous obtenons

bc#double => self#set(cont*2)  avec self = bc
          => bc#set(cont*2)
          => backup <- cont; super#set(cont*2)
          => backup <- cont; cont <- cont*2
          => backup <- 1; cont <- 2

Ainsi, lors de la compilation de self#set(cont*2), le choix du code à invoquer pour la méthode set est retardé jusqu'au moment de l'exécution, quand il est possible d'établir dynamiquement une liaison pour self. C'est à ce moment-là que le code pour set est selectionné: il s'agit de celui dans l'objet lié à self. Dans notre cas, il s'agit du code de set dans bc.

Dans notre exemple, il est important de comprendre que le code exécuté, n'est pas celui qui correspond à une liaison statique pour la méthode set. La méthode double invoquée est celle héritée de cell. Or, double invoque à son tour sa méthode soeur set. Dans la mesure où cette demande apparaît textuellement dans cell, on peut s'interroger: s'agit-il de set dans cell ou dans backupCell? Le schéma suivant montre la pertinence de la question:

class cell =
   ...
     method set n  = ...
     method double = self#set (cont*2)   (* quel methode set ici ? *)
   ...
end

class backupCell =
  ...
    inherit cell 
    method  set n = (* methode redefinie *)
  ...
end

Comme dans le cas précédent, nous avons deux choix possibles

Liason statique $\Rightarrow$ self#set(cont*2) exécute le code dans cell

Liason tardive

$\Rightarrow$ self#set(cont*2) exécute le code dans backupCell


Et comme dans le cas précédent, le choix de la méthode est retardé jusqu'à l'exécution. Cette fois, c'est grâce à l'invocation de set via self, et au mécanisme de liaison dynamique pour celui-ci, que le choix de code pour set devient retardé.


next up previous
Next: Liaison tardive et représentation Up: Liaison tardive Previous: Polymorphisme et liaison tardive
Maria-Viginia Aponte
2001-03-28