next up previous
Next: Types récursifs Up: Types et objets en Previous: Classes paramétrées par un

Contraintes de typage

La classe ['a] pile est paramétrée par le type 'a des éléments dans la pile, par la valeur x d'initialisation, et par sa taille maximale n6. Selon l'usage des valeurs polymorphes à l'intérieur d'une classe, des contraintes peuvent apparaître dans l'interface inférée.

class ['a] pile ((x : 'a), n) =
 object(self) 
   val mutable ind = 0
   val tab = Array.create n x
   method is_empty = ind = 0 
   method private is_full = ind = n+1
   method pop = if self#is_empty then failwith "pile vide"
                else ind <- ind - 1; tab.(ind) 
   method push y = if self#is_full then failwith "pile plaine"
                  else tab.(ind) <- y; ind <- ind + 1
   method top = if self#is_empty then failwith "pile vide"
                else (tab.(ind-1))#print 
 end;;
L'interface de cette classe rend compte de la contrainte imposée par la méthode top: les composants de la pile sont des objets avec au moins une méthode print:

class ['a] pile :
  'a * int ->
  object
    constraint 'a = < print : 'b; .. >
    val mutable ind : int
    val tab : 'a array
    method is_empty : bool
    method private is_full : bool
    method pop : 'a
    method push : 'a -> unit
    method top : 'b
  end

Les contraintes de type peuvent aussi être explicites. La classe virtuelle printable possède une unique méthode (virtuelle) print. La nouvelle définition de pile, contraint le type des éléments à être une instance polymorphe de printable, autrement dit, à possèder au moins une méthode print du bon type.

class virtual printable =
 object 
  method virtual print : unit
 end;;

class ['a] pile ((x : 'a), n) =
 object(self) 
   constraint 'a = #printable
   val mutable ind = 0
   val tab = Array.create n x
   method is_empty = ind = 0 
   method private is_full = ind = n+1
   method pop = if self#is_empty then failwith "pile vide"
                else ind <- ind - 1; tab.(ind) 
   method push y = if self#is_full then failwith "pile plaine"
                  else tab.(ind) <- y; ind <- ind + 1
   method top = if self#is_empty then failwith "pile vide"
                else (tab.(ind-1))#print 
 end;;

qui donne l'interface:

class ['a] pile :
  'a * int ->
  object
    constraint 'a = #printable
    val mutable ind : int
    val tab : 'a array
    method is_empty : bool
    method private is_full : bool
    method pop : 'a
    method push : 'a -> unit
    method top : unit
  end
Un exemple de sous-classe de printable:
# class printable_int i =
  object 
  inherit printable
  val x = i
  method print = print_int x
end;;

class printable_int : int -> object val x : int method print : unit end

(* Exemples d'utlilisation *)

# let un = new printable_int 1;;
val un : printable_int = <obj>

# let deux = new printable_int 2;;
val deux : printable_int = <obj>

# let pile10 =  new pile (un,10);;
val pile10 : printable_int pile = <obj>

# pile10#push deux;;
- : unit = ()

# pile10#top;;
2- : unit = ()



Maria-Viginia Aponte
2001-04-10