![]()
![]()
![]()
![]()
![]()
Next: Fonction générique prédéfinie Up: Fonction générique Previous: Présentation   Contents   Index
Subsections
Fonctions génériques Les fonctions génériques vont permettre de définir des méthodes applicables aux objets.
Déclaration
Les fonctions génériques se déclarent avec
define-genericet se définissent avecdefine-method.La première forme,
define-generic, déclare la variable Scheme correspondante à la fonction générique :; Déclaration d'une méthode Osm> (define-generic f) => #unspecified
Utilisation
Une fois que la fonction générique est déclarée, elle peut être utilisée :
; Invocation de la méthode Osm> (f) => OsmError: f: no generic method found for `()'L'erreur obtenue indique qu'aucune méthode n'est définie pour la liste d'argument donnée, c'est à dire la liste vide.
Définition
Pour définir une méthode, nous utilisons
define-method:; Définition de la méthode Osm> (define-method (f) (display "(f)\n")) => #unspecifiedNous venons de définir une méthode
florsquefsera invoquée sans argument. Essayons :Osm> (f) => (f) => #unspecifiedL'intérêt des fonctions génériques est de permettre de réutiliser le nom de la méthode pour d'autres arguments :
; Spécialisation avec un argument Osm> (define-method (f a) (display "(f a)\n")) => #unspecifiedCette méthode sera invoquée lorsque
fsera appliquée à un argument, quel que soit son type :Osm> (f 1) => (f a) => #unspecifiedPour deux arguments de n'importe quel type :
; Spécialisation avec deux arguments Osm> (define-method (f a b) (display "(f a b)\n")) => #unspecified Osm> (f 1 #\a) => (f a b) => #unspecified
Spécialisation
Mais ça ne s'arrête pas là : il est possible d'augmenter la résolution en précisant le type des arguments. Définissons la méthode
f, appliquée à un entier de la classe: ; Spécialisation avec un argument <integer> Osm> (define-method (f (a <integer>)) (display "(f <integer>)\n")) => #unspecified Osm> (f #\a) => (f a) => #unspecified Osm> (f 1) => (f <integer>) => #unspecifiedLa méthode
fa été spécialisée pour un seul argument entier. La définition pour un seul argument d'un autre type reste toujours valide.Cela est applicable pour tous les arguments :
; Spécialisation avec deux arguments, ; dont le second <integer> Osm> (define-method (f a (b <integer>)) (display "(f a <integer>)\n")) => #unspecifiedIci, on spécialise
florsque son second argument appartient à la classe. Lorsque OpenScheme applique une méthode générique à des arguments, il commence à compter le nombre des arguments, puis il recherche dans un arbre interne la méthode correspondant le mieux à la classe des arguments, en commençant par la classe la plus spécialisée. Une classe
Aest plus spécialisée qu'une classeBlorsqueAhérite deB.Tout objet Scheme appartient à la classe primitive
. Lorsque l'on définit une méthode avec un argument sans type, en fait le type associé à celui-ci est . Ceci permet d'avoir un comportement orthogonal. Les méthodes génériques ne permettent pas de définir des fonctions avec des arguments facultatifs, comme c'est le cas en Scheme.
Précédence
Le système objet ne se contente pas de sélectionner la méthode la plus adéquate en fonction des arguments passés : il permet à une méthode d'invoquer la méthode qui aurait était invoquait si elle n'avait pas été définie. Cette invocation se fait à l'aide de la fonction spéciale
next-method:; déclaration de la fonction générique Osm> (define-generic g) => #unspecified ; définition dans le cas général Osm> (define-method (g a) (display "cas <root>\n")) => #unspecified ; spécialisation Osm> (define-method (g (a <integer>)) (next-method) (display "cas <integer>\n")) => #unspecified ; essais du cas <root> Osm> (f #\a) => cas <root> => #unspecified ; essais du cas <integer> Osm> (f 123) => cas <root> => cas <integer> => #unspecifiedL'invocation de
next-methodse fait sans argument. En fait, cet appel est remplacé par l'appel à la méthode suivante dans l'arbre de recherche, avec tous les arguments.Cela permet de chaîner les méthodes. Si aucune méthode moins spécialisée, l'invocation de
next-methodne provoque pas d'erreur.
![]()
![]()
![]()
![]()
![]()
Next: Fonction générique prédéfinie Up: Fonction générique Previous: Présentation   Contents   Index © 1993 to 2001 Erian Concept