next up previous contents index
Next: Fonction générique Up: Structures de données et Previous: Définition d'une classe virtuelle   Contents   Index

Subsections


Classes construites

Les classes virtuelles permettent d'utiliser les objets Scheme standard dans le système orienté objet d'OpenScheme.

Les classes construites permettent de définir de nouveaux types d'objets en utilisant les possibilités offertes par les méthodes orientées objet.

Le définition d'une classe se fait à l'aide de la fonction define-classe dont la syntaxe est la suivante :

(define-class
   nom      ; nom de la classe
   super    ; super classe
   champ-1  ; premier champ
   champ-2  ; second champ
   ...      ; champs suivants
   )

L'argument nom est le nom de la classe définie, super est la classe dont va hériter la classe que l'on est en train de définir ; lorsque la classe n'hérite d'aucune autre classe, l'argument vaut #f.

Les champs de la classe sont champ-1, champ-2, etc. Ils sont soit un symbole représentant le nom du champ, soit une liste dont le premier élément est un symbole représentant le nom du champ et les éléments suivants, les options du champ.

Lorsqu'une classe est définie, deux fonctions par champ sont aussi définies, l'une pour la lecture de la valeur du champ, et l'autre pour l'écriture. Par défaut, ces procédures sont déclarées comme :

; lecteur
(define (classe:champ  objet)...)

; écrivain
(define (classe:champ! objet valeur)...)

classe est le nom de la classe définie, et champ, le nom du champ. Si la classe hérite d'une autre classe, des procédures identiques sont déclarées pour chacun des champs hérités.

Ainsi, la déclaration :

(define-class <a> #f x y)

déclare la classe sans héritage, qui possède les champs x et y, sans option. Les procédures suivantes sont aussi déclarées :

; prédicat
(define (<a>? objet) ...)

; champ x
(define (<a>:x self) ...)
(define (<a>:x! self value) ...)

; champ y
(define (<a>:y self) ...)
(define (<a>:y! self value) ...)

Lorsque les champs possèdent des options, ils sont déclarés dans une liste dont le premier élément est le nom du champ, et les éléments suivants, ses options. Les options de champs peuvent être :

Création

Après avoir définit des classes, il est possible de créer des objets correspondants avec la fonction build :

Osm> (define-class 
       <a>   ; nom de la classe
       #f    ; pas d'héritage
       x     ; premier champ
       y     ; second champ
       )
  => #unspecified

Osm> (define un-objet 
            (build <a>
             ; x initialisé à 123
             :x 123))
  => #unspecified

La procédure build retourne une nouvelle instance de la classe donnée en argument. Les champs peuvent être initialisés lors la création en utilisant leur nom préfixés par le caractère :, suivit de la valeur du champ. Les champs non-initialisés ont comme valeur #unbounded ou la valeur introduite par l'option :initform.

On pourrait écrire :

Osm> (<a>? un-objet)
  => #t

Osm> (<integer>? un-objet)
  => #f

Osm> (<root>? un-objet)
  => #t

Osm> (<a>:x un-objet)
  => 123

Osm> (<a>:y un-objet)
  => #unbounded

Osm> (<a>:y! un-objet 456)
  => #unspoecified

Osm> (<a>:y un-objet)
  => #456

En utilisant les options des champs, on a :

Osm> (define-class <a> #f
                   [x :initkey the-x
                      :class <integer>]
                   [y :initform 456])
  => #unspecified

Osm> (define un-objet (build <a> :the-x 123))
  => #unspecified

Osm> (<a>:x un-objet)
  => 123

Osm> (<a>:y un-objet)
  => 456

Osm> (<a>:x! un-objet "une chaîne")
  => OsmError: <integer> required instead of <string>

L'option :virtual permet de calculer la valeur d'un champ. Par exemple :

Osm> (define-class <a> #f
                   [x :virtual
                      ; lecteur en premier
                      (lambda (self)
                       (+ (<a>:y self) 34))
                      ; lecteur en premier
                      (lambda (self value)
                       (- (<a>:y! self) 34))]
                   [y :initform 456])
  => #unspecified

Osm> (define un-objet (build <a>))
  => #unspecified

Osm> (<a>:x un-objet)
  => 422

Osm> (<a>:y un-objet)
  => 456

Osm> (<a>:x! un-objet 123)
  => #unspecified

Osm> (<a>:x un-objet)
  => 55

Osm> (<a>:y un-objet)
  => 89

next up previous contents index
Next: Fonction générique Up: Structures de données et Previous: Définition d'une classe virtuelle   Contents   Index
© 1993 to 2001 Erian Concept