Les propositions suivantes sont equivalentes
(1) la sorteC denie par ces generateurs est habitee
(2) la classeC est habitee
(3) il existe un vecteur caracteristique v tel que pr ofil
v soit compose de classes habitees et
non structurellement dependantes deC et il existe un n-upletude pr ofil
v qui satisfait pr ec
v.
Certaines conditions necessaires pour avoir une classe habitee peuvent ^etre veriees facile- ment. Par exemple, sin= 0 alors la classe est un singleton contenant une seule constante, ou
encore, siT iDPS
C alors cela implique que pr ec i
6tr ue.
Il est plus dicile de denir une forme generale et susante pour une classe habitee, en particulier l'usage des preconditions interdit toute chance d'avoir un critere statiquement de- cidable. La puissance d'expression du schema suivant n'est pas connu mais en pratique elle semble assez generale.
Principe 6.2.11 (Aspect susant)
C
aspect : aspect suffisant
eld selectors constraint
fsel 1 : C ?! S 1 ... : C ?! ... fselk : C ?! Sk cont csel1 : C ?! D1 requires: pr ec 1 ... : C ?! ... requires: ... csel r : C ?! D r requires: pr ecr { Soitr= 0 ^ k= 0 { Soitk1etr= 0alors: S i
D PS C pour 1ik et sont habitees.
{ Soitk1et8 1j r pr ec j
6tr ue6fal se,
alors:S i
D PS C pour 1ik et sont habitees et il existe un n-upletu2 Q k i=1 S i tel quepr ec j( u) 1jrest faux.
La structure inductive des termes est denie par les generateurs de l'interpretation prece- dente. Notons que la denition de ce type de structure nous permet de denir une notion de representation [Hoa72, Gut80]. Ceci ouvre la voie a des aspects pratiques interessants : compa- raison d'aspects, notion de representation plus abstraite etc.
6.2.5 Proprietes
Denition 6.2.12 (classe bien denie)
Une classe C est bien denie si elle possede les trois proprietes suivantes:
1. La classe est habitee.
2. La specication associee est non-contradictoire:
8 t;u2T C ; t;u:P (P 2USE(C)); ` C t==u=) ` P t==u.
3. La specication est pleinement speciee :
8c2T C
; c:P (P 2USE(C)); 9u2T P
La premiere condition assure une induction bien fondee sur les instances de la classe. Dans ce cas, la validite de la deduction equationnelle classique est egalement assuree [GM85, Sun91]. La deuxieme condition exprime que des termes predenis qui etaient initialement distincts ne sont pas rendus egaux. La derniere condition dit que l'action de tout observateur est connu sur tous les objets de la classe. Nous nous sommes inspires de la pleine specication de [Mus80] plu- t^ot que de la completude hierarchique [Gau90] car cette derniere est trop contraignante en objet. La methode de conception a objets est incrementale: le concepteur denit d'abord la ca- racterisation des objets puis il etend successivement le comportement tout en conservant cette caracterisation.
Propriete 6.2.13 (bonne denition des primitives)
Une classe reduite a son aspect (i.e. sans extension) est bien denie si et seulement si la classe est habitee.
Cette propriete se justie en considerant d'abord une denition sans contrainte ni condition de selecteur de champ. Dans ce cas il peut ^etre prouve que le systeme d'equations peut s'orienter en regle de reecriture de droite a gauche. Ce systeme est convergent (donc non-contradictoire) car il est sans superposition et il est facile de trouver un ordre de reduction qui termine. La pleine specication est facile a verier. Dans le cas ou il y a des conditions, celles-ci sont de- nies sur les types structurants donc bien denies par hypothese. Les preconditions ajoutees aux equations ne changent rien au niveau de la terminaison et n'ajoutent pas de superposition. Elles peuvent avoir une in uence sur la pleine specication, mais nous avons fait l'hypothese d'un traitement d'erreur complet.
Soit une classe C, C +m designe l'extension de la classe C par l'ajout de la methodem. Cet
ajout peut ^etre une nouvelle methode ou encore la redenition d'une methode existante.
Denition 6.2.14 (extension bien denie)
SoitCune classe bien denie,mest une extension bien denie pourC si et seulement siC +m
est encore une classe bien denie.
Il existe des criteres d'ecriture qui assure la bonne denition d'une methode (cf section 6.2.6). Ils s'inspirent de ceux utilises en specication algebriques [Gut80, Bid82].
Propriete 6.2.15 (Extension incrementale)
L'ajout d'une extension bien denie ne modie pas l'aspect de la classe.
Cette propriete decoule du fait qu'une nouvelle extension ne modie pas la semantique des methodes primitives.
6.2.6 Ecriture des methodes
Nous commentons dans cette section quelques idees d'ecriture des axiomes pour les exten- sions. Une condition susante pour qu'une methode soit bien denie est qu'elle soit une ex- tension non-contradictoire des methodes deja denies dans la classe. Cette situation est simple et generale a utiliser, dans [AR92c] nous avons appeles de telles methodes
methodes secon-
daires
. Les techniques usuelles [GH78, Mus80, Bid82, LG90, BB92] sont une autre sources d'inspiration.La denition d'une extension peut rev^etir plusieurs formes: nous en donnons une ici. Nous en verrons d'autres dans la section 6.6.1.
Denition 6.2.16 (presentation quasi-operationnelle)
C'est une regle de reecriture de la forme e(Self;) ?!t ou eest l'extension a denir et tun
extensions
;; newtotal : modification du solde de la carte - extension directe
newtotal : Carte Integer ?! Carte
var: somme:Integer
newtotal(Self, somme) ?! newCarte(idClient = idClient(Self),
cumul = cumul(Self) + somme, date = date(Self)) ;; newtotal : modification du solde de la carte - extension indirect
newtotal : Carte Integer ?! Carte
var: somme:Integer
newtotal(Self, somme) ?! copy(Self, cumul = cumul(Self) + somme)
;; append : concatenation de deux listes - extension recursive
append : FullListC ListC ?! FullListC
var: Xl:ListC
append(Self, Xl) == cons(car(Self), append(cdr(Self), Xl))
Dans le cas d'une modication de methode existante ou d'un ajout d'une nouvelle methode, il faut globalement reconsiderer la propriete de bonne denition de la classe.
6.2.7 Classe abstraite, methode abstraite
Les proprietes generales communes a un ensemble de classes et les comportements partiels sont denis par des classes et des methodes abstraites.
Denition 6.2.17 (classe abstraite)
Une classe abstraite est une classe qui ne possede pas de methode de creation d'instance.
Denition 6.2.18 (methode abstraite)
Une methode abstraite ou methode virtuelle est une extension dont les axiomes ne sont pas decrits.
Les termes produits par une extension n'etant pas denis la contradiction et la pleine speci- cation de la propriete 6.2.12 ne sont pas demontrables. En consequence, une classe contenant une methode abstraite doit ^etre declaree abstraite.
Une methode (resp. une classe) est declaree abstraite par le mot-cleABSTRACT. La fonction abstract(m)(resp. abstract(C)) indique si une methodem(resp. une classeC) est abstraite.
Exemple:
Boolean ABSTRACT
inherits from OBJECT
extensions
;; and : conjunction
and : Boolean Boolean ?! Boolean ABSTRACT
;; not : negation
not : Boolean ?! Boolean ABSTRACT
;; or : disjunction
or : Boolean Boolean ?! Boolean
var: b:Boolean
or(Self, b) == not(and(not(Self),not(b))) ;; xor : exclusive disjunction
xor : Boolean Boolean ?! Boolean
var: b:Boolean
xor(Self, b) == and(or(Self,b),not(and(Self,b))) ;; implies : implication
implies : Boolean Boolean ?! Boolean
var: b:Boolean
True
inherits from Boolean
extensions
;; and : conjunction
and : TrueBoolean ?! Boolean
var: b:Boolean and(Self, b) == b ;; not : negation
not : TrueBoolean ?! False not(Self) == newFalse
False
inherits from Boolean
extensions
;; and : conjunction
and : False Boolean ?! False
var: b:Boolean and(Self, b) == Self ;; not : negation
not : False Boolean ?! True not(Self) == newTrue
Figure 47 : La specication des booleens par classes formelles.
Les theoremes suivants servent a la redenition des methodesor, xor, impliesdans les
sous-classes TrueetFalse:
8 b:Boolean, t:True, f:False,
or(t, b) == Self or(f, b) == b xor(t, b) == not(b) xor(f, b) == b implies(t, b) == b implies(f, b) == not(f) implies(f, b) == newTrue
Les denitions et proprietes precedentes sur les classes et les methodes doivent ^etre adaptees pour prendre en compte les classes abstraites.
Une classe abstraite n'est pas a proprement parler habitee puisqu'elle n'a pas d'instances. Le probleme se pose pour les classes qui dependent structurellement de cette classe abstraite e.g. la classe ClientHonn^etedepend structurellement de la classe abstraite Boolean (page 133).
Plusieurs denitions sont possibles.
Denition6.2.19(classe abstraitehabitee)
Une classe abstraite est habitee si elle a au moins une sous-classe et que toute ses sous-classes sont habitees.
Cette denition est correcte mais pose le problemes de la validite dans le temps: la veri- cation doit ^etre refaite a chaque fois que la sous-hierarchie de la classe abstraite est modiee. La propriete d'extension incrementale du systeme de classe n'est pas conservee. Une denition plus faible serait qu'il existe au moins une sous-classe habitee. Cette contrainte est moins forte mais n'assure pas la bonne denition des classes. Une derniere denition, plus souple, simule une classe abstraite par une classe concrete. La notion de classe habitee devient alors celle de classe (potentiellement) habitable dans les denitions de la section 6.2.5 lorsque les classes sont abstraites.
Denition6.2.20(classe abstraitehabitable)
Cette denition est possible a cause de la preservation de l'aspect par heritage (voir section suivante) et que toute instance apparaissant dans l'aspect sera une instance d'une sous-classe. La propriete 6.2.12 n'est pas decidable, mais une bonne denition des extensions est possible en ajoutant les methodes abstraites dans l'ensemble F des operations sur lesquelles sont denies les extensions non abstraites, selon la denition 6.2.5.
6.3 Heritage
L'heritage d'aspect et celui des extensions sont distingues, L'heritage d'aspect est une re- lation proche du sous-typage, qui permet de decider si une classe peut heriter d'une autre. Elle est basee sur la relation de crcition appelee projection structurelle [Roy92]. L'heritage de comportement est un mecanisme de reutilisation de code. Cette distinction n'entra^ne pas deux hierarchies, a la dierence de VDM++[D94] ou l'heritage de structure est simple et l'heritage de comportement est independant et multiple.
6.3.1 Crcition
Cette denition se base sur une correspondance entre les selecteurs de champ de S et ceux de C : la contrainte est respectee, les preconditions renforcees, et les types restreints. Cette correspondance se fait par egalite des noms de selecteurs, pour simplier nous supposons les selecteurs ordonnes de telle facon que 8i 1 i n; name(fselSi) = name(fselCi), ou n
represente le nombre de selecteurs de S.
Denition6.3.1 (projectionstructurelle)
SoientS etC deux classes,coerce(C;S) : TC
?!TS est deni par
{ 8c2TC; contC(fselC 1(c); :::; fselCm(c)) = ) contS(fselS 1(c); :::fselSm(c)) et { 8fselSi : S ?!Ti; 1inet fselCi : C ?!Ri { soitnot(precCi(c))
{ soitprecCi(c)^precSi(c) et
{ soitTi = Ri ^ fselCi(c) = fselSi(c)
{ soit9coerce (R i;Ti ) ^ coerce (R i;Ti
)(fselCi(c)) = fselSi(coerce(C;S)(c)).
{ 8c2TC; abstract(S) =)coerce
(C;S)(c) = c Propriete6.3.2 ()
Si cette relation existe elle est unique et elle denit un ordre partiel sur les classes.
Cette denition utilise l'egalite des noms de selecteurs de champ, en pratique il peut ^etre utile d'envisager la projection structurelle apres un renommage adequat. La denition de la crcition se fait en comparant les classes (sans heritage). L'heritage est considere comme une propriete decoulant de cette relation.
Denition6.3.3 (heritage)
SoientS et Cdeux classes distinctes alors Cpeut heriter de S si et seulement si il existe une projection structurelle deTC versTS.
C ako S ()9coerce (C;S)
^ (:abstract(S)):abstract(C))
L'heritage est donc autorise si de la super-classe vers la sous-classe : - L'aspect contient les memes selecteurs de champ.
- Le codomaine des selecteurs de champ est plus specique, - Les selecteurs de champ ont une precondition plus forte. - La contrainte est plus restrictive.
Ces dierents cas pouvent se combiner. Le dernier cas correspond plus a une bonne habitude de programmation qu'une condition necessaire : une classe abstraite represente un comportement partiel, qui est complete dans les sous-classes et il n'est pas logique de denir un comportement partiel a partir d'un comportement total. Noter que cette forme d'heritage entra^ne le sous- typage, selon des regles que nous examinerons dans la section 6.5.
6.3.2 Heritage des methodes
La validite de l'heritage structurel etant etablie, etudions ses consequences au niveau des methodes. Seules les extensions sont heritees puisque les primitives sont implicitementredenies par la classe. Nous nous placons dans un contexte restrictif (mais souhaitable en genie logiciel) ou il n'y a pas d'exception a l'heritage des methodes.