next up previous
Next: Sous-typage entre fonctions Up: Sous-classe Sous-type Previous: Un exemple en dehors

Les méthodes binaires

Nous fermons maintenant la parenthse ``immaginaire'' et revenons à Ocaml tel qu'il fonctionne réellement. Les opérations binaires, à savoir, celles qui prennent deux arguments de même type sont courantes en informatique. Des exemples sont: l'addition, l'égalité, les opérations sur les ensembles (union, intersection), etc. En Programmation OO, ces opérations sont usuellement définies par des méthodes où le premier argument est l'objet receveur du message (et est donc implicite) et le deuxième argument est le seul véritable argument de la méthode. Considérons par exemple, la classe point qui définit une méthode pour comparer deux points par égalité:

class point init  =
 object(self: 'a)
  val mutable x = init
  method getx = x
  method move d = x<-x+d
  method equal (y:'a)  = y#getx = self#getx
  end;;

class colorpoint x (c:string) =
 object(self: 'a)
  inherit point x as pointsup
  val mutable c = c
  method getcolor = c
  method setcolor c' = c<-c'
  method equal (y: 'a)  = 
     (y#getcolor = self#getcolor) & pointsup#equal y
  end;;
Examinons les interfaces données pour ces deux classes:
 class colorpoint x (c:string) =
 object(self: 'a)
  inherit point x as pointsup
  val mutable c = c
  method getcolor = c
    method setcolor c' = c<-c'
  method equal (y: 'a)  =
     (y#getcolor = self#getcolor) & pointsup#equal 
  end;;
class colorpoint :
  int ->
  string ->
  object ('a)
    val mutable c : string
    val mutable x : int
    method equal : 'a -> bool
    method getcolor : string
    method getx : int
    method move : int -> unit
    method setcolor : string -> unit
  end
et, considérons la fonction suivante:

let breakit (p) =
  let pt = new point 1 in  (p :> point)#equal(pt);;
val breakit :
  < equal : point -> bool; getx : int; move : int -> unit; .. > -> bool

Supposons que colorpoint est un sous-type de point. Alors, on doit pouvoir employer tout point de couleur comme un point. En particulier, la coercion colorpoint :> point doit être possible. Cette coercion est réalisée dans le code de breakit. Ainsi, si colorpoint est un sous-type de point, on doit pouvoir réaliser l'appel breakit(cp) qui à son tour, éffectue cette coercion.

# let cp = new colorpoint 3 "Rouge";;
val cp : colorpoint = <obj>

breakit(cp);;
$\Rightarrow$ p#equal(pt)
$\Rightarrow$ cp#equal(pt)
$\Rightarrow$ (pt#getcolor = cp#getcolor) & pointsup#equal(cp)
$\Rightarrow$ erreur (car pt n'a pas de méthode getcolor)

Si cet appel était executé, une erreur se produit au moment d'évaluer le corps de la fonction: p#equal(pt). En effet, puisque p = cp , alors le code executé pour equal est celui de colorpoint (grâce à la liaison tardive), et alors celui-ci enverra le message getcolor à pt. Or, pt est de type point et ne sait pas comme interpreter ce message et produira donc une erreur. Ainsi, il n'est pas sûr du point de vue du typage d'admettre que colorpoint soit un sous-type de point. Idéalement, un appel à breakit avec un argument effectif de type colorpoint doit être interdit, et ceci par un échec pendant le typage. C'est ce qui se passe en OCaml, qui répond par un long message d'erreur:

# breakit(cp);;
          ^^
This expression has type
  colorpoint =
    < equal : colorpoint -> bool; getcolor : string; getx : int;
      move : int -> unit; setcolor : string -> unit >
but is here used with type
  < equal : point -> bool; getcolor : string; getx : int; move : int -> unit;
    setcolor : string -> unit >
Type
  colorpoint =
    < equal : colorpoint -> bool; getcolor : string; getx : int;
      move : int -> unit; setcolor : string -> unit >
is not compatible with type
  point = < equal : point -> bool; getx : int; move : int -> unit > 
Only the first object type has a method getcolor

Ce message nous dit que seul l'argument de type colorpoint a une méthode getcolor: il nous previent sûr la cause de l'erreur qui surviendrait si ce code était executé.

Les classes point et colorpoint montrées plus haut ne sont pas en relation de sous-typage. La raison est que les types des deux méthodes equal (dans chacune des deux classes) ne sont pas en relation de sous-typage. L'explication est assez technique et est donnée dans la partie suivante.


next up previous
Next: Sous-typage entre fonctions Up: Sous-classe Sous-type Previous: Un exemple en dehors
Maria-Viginia Aponte
2001-04-10