Académique Documents
Professionnel Documents
Culture Documents
Heritage
Ce chapitre du cours traite de concepts relatifs a` la programmation objet (hierarchie de classe,
heritage, extension, masquage) et sera illustre par un exemple de representation de comptes bancaires
et doperations liees a` la manipulation de ceux-ci (retrait, depot, consultation).
CHAPITRE 16. HERITAGE
p u b l i c v o i d d e p o t ( double m o n t a n t ) {
t h i s . solde + = montant ;
}
p u b l i c v o i d r e t r a i t ( double m o n t a n t )
throws p r o v i s i o n I n s u f f i s a n t e E r r e u r {
System . o u t . p r i n t l n ( Appel de r e t r a i t s u r compte s i m p l e ) ;
i f ( t h i s . solde < montant ){
throw new p r o v i s i o n I n s u f f i s a n t e E r r e u r ( ) ;
}else{
s o l d e = m o n t a n t ;
}
}
p u b l i c v o i d v i r e m e n t ( C o m p t e B a n c a i r e c , double m o n t a n t )
throws p r o v i s i o n I n s u f f i s a n t e E r r e u r {
c . r e t r a i t ( montant ) ;
t h i s . depot ( montant ) ;
}
}
c l a s s p r o v i s i o n I n s u f f i s a n t e E r r e u r extends Exception {
}
NOTION DHERITAGE
pacter tout programme (ou toute classe) qui utilise cette classe et conduit a` une difficulte : comment
definir un compte remunere sans decouvert ou un compte avec decouvert possible mais non remunere.
Il faudrait dans ce cas dupliquer a` la main ces classes pour les particulariser ; il nest pas difficile
dimaginer lensemble des modifications quentranerait cette solution sur les programmes utilisant la
classe CompteBancaire.
Les langages de programmation modernes offrent differentes solutions a` ce probl`eme ; le but est
chaque fois de permettre une extension ou une specialisation des types de base. Avec la programmation par objets ceci se realise naturellement avec la notion dh eritage. Le principe consiste a` definir
une nouvelle classe a` partir dune classe existante en ajoutant des donnees a` cette classe et en
reutilisant de facon implicite toutes les donnees de la classe de base. Si A est la classe de base et si
B est la classe construite a` partir de A on dit que B herite de A ou encore que B specialise A
ou encore que B derive de A. On dira e galement que A est la classe m`ere de B et que B est une
sous-classe, ou une classe fille de A. Dans le cas o`u une classe herite dune seule classe (cest le
cas en Java) on parle dheritage simple (au lieu dheritage multiple) et la relation m`ere-fille definit un
arbre comme represente par le dessin suivant o`u B1 et B2 heritent de A et o`u C herite de B1 (et donc
e galement par transitivite de A). On notera quen Java toute classe herite de la classe Object.
A
B1
B2
Ceci permet de prendre en compte lenrichissement (ou la specialisation) que la classe fille
apporte par rapport a` la classe m`ere en specialisant le code de la methode. Lorsque dans une
classe derivee on souhaite designer une methode (ou une donnee) de la classe m`ere (et en
particulier lorsque celle-ci est masquee) on designe celle-ci en prefixant le nom de la methode
(ou de la variable) par super. Ainsi, si B derive de A et si x est un nom utilise dans A et B, la
denomination super.x dans une methode de B designera x relatif a` A et non x relatif a` B (qui
serait designe par this.x). Dans le cas particulier du constructeur, un appel a` super designe
un appel au constructeur approprie (celui dont le nombre et le type des param`etres conviennent)
de la classe m`ere.
La syntaxe utilisee en Java pour definir quune classe B e tend une classe A consiste a` preciser lors
de la declaration de la nouvelle classe cette extension avec la notation class B extends A. Tout
ce qui sera defini au niveau de cette nouvelle classe B sera propre a` B ; tout ce qui nest pas redefini
sera herite de A, cest-`a-dire quun objet instance de B pourra acceder a` ces donnees ou methodes
comme un objet instance de A.
Appliquons ces principes a` la construction de deux classes derivees de la classe CompteBancaire.
La premi`ere permettra de representer des comptes bancaires avec decouvert autorise ; la seconde prendra en compte une possible remuneration du compte. Pour le premier type de compte, il faut preciser
quel est le decouvert maximum autorise. Pour le second type de compte, il faudra definir quel est la
remuneration (taux) et, par exemple, quel est le seuil minimal a` partir duquel la remuneration sapplique.
CHAPITRE 16. HERITAGE
6
}
On peut alors definir un compte remunere avec decouvert autorise. Il suffit pour cela de deriver de
la classe CompteRemunere la classe CompteRemunereAvecDecouvert. Cela se fait simplement de la facon suivante (il suffit dintroduire une nouvelle variable et un nouveau constructteur et
de redefinir la methode de retrait) :
p u b l i c c l a s s CompteRemunereAvecDecouvert e x t e n d s CompteRemunere {
double d e c o u v e r t M a x ;
p u b l i c v o i d f i x e D e c o u v e r t M a x i m a l ( double m o n t a n t ) {
t h i s . decouvertMax = montant ;
}
p u b l i c CompteRemunereAvecDecouvert ( S t r i n g p r o p r i o ,
char [ ] num ,
double m o n t a n t ,
double t a u x ,
double d e c o u v e r t M a x ) {
super ( p r o p r i o , num , m o n t a n t , t a u x ) ;
/ / i c i s u p e r d e s i g n e l a c l a s s e CompteRemunere
fixeDecouvertMaximal ( decouvertMax ) ;
}
p u b l i c v o i d r e t r a i t ( double m o n t a n t )
throws p r o v i s i o n I n s u f f i s a n t e E r r e u r {
System . o u t . p r i n t l n (
Appel de r e t r a i t s u r compte r e m u n e r e a v e c d e c o u v e r t ) ;
i f ( t h i s . s o l d e montant < decouvertMax ){
throw new p r o v i s i o n I n s u f f i s a n t e E r r e u r ( ) ;
CompteAvecDecouvert
CompteRemunere
CompteRemunereAvecDecouvert
On notera que, la methode retrait utilisee lors de ces instructions est celle qui est redefinie dans
la nouvelle classe. La methode fixeTaux est par contre la methode herite de la classe CompteRemunere
CHAPITRE 16. HERITAGE
et les methodes depot et soldeCourant sont celles heritees de la classe m`ere CompteBancaire.
On le voit, lheritage est transitif.
CompteBancaire c ;
S t r i n g num = AAA4AA54 ;
Les r`egles de typages de Java font quil est possible dassocier a` c par creation un compte ordinaire
ou un compte avec decouvert. En effet, toute classe est compatible avec ses sous-classes, et donc, c
qui est de la classe CompteBancaire est compatible avec la classe CompteAvecDecouvert.
Les deux instructions
c = new C o m p t e B a n c a i r e ( Marie , num . t o C h a r A r r a y ( ) , 1 0 0 0 0 . 0 0 ) ;
c = new CompteAvecDecouvert ( Marie , num . t o C h a r A r r a y ( ) , 1 0 0 0 0 . 0 0 , 0 . 0 ) ;
sont donc correctes ; dans le premier cas, c sera de classe reelle CompteBancaire et dans le
second cas de classe reelle CompteAvecDecouvert. Donc, linstruction c.retrait(100.00)
appelera soit la methode retrait des comptes avec decouvert (second cas) soit la methode retrait
des comptes ordinaires. Cette liaison entre appel et methode peut se faire lors de la compilation (dans
le cas o`u le compilateur a suffisamment dinformations pour calculer cette liaison) ou simplement
lors de lexecution du programme ; on parle alors de liaison tardive. La suite dinstructions suivantes
illustre ce mecanisme : selon la reponse faite par lutilisateur, le programme associe a` c un compte
ordinaire ou un compte avec decouvert.
public clas s TestLiaisonTardive{
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
CompteBancaire c ;
S t r i n g num = AAA4AA54 ;
T e r m i n a l . e c r i r e S t r i n g ( Voulez vous c r e e r un compte d e c o u v e r t O/ N : ) ;
char r e p o n s e ;
reponse = Terminal . l i r e C h a r ( ) ;
i f ( ( r e p o n s e ! = O ) & & ( r e p o n s e ! = o ) ) {
T e r m i n a l . e c r i r e S t r i n g ( C r e a t i o n d un compte o r d i n a i r e ) ;
c = new C o m p t e B a n c a i r e ( Marie , num . t o C h a r A r r a y ( ) , 1 0 0 0 0 . 0 0 ) ;
}
else {
T e r m i n a l . e c r i r e S t r i n g ( C r e a t i o n d un compte a v e c d e c o u v e r t ) ;
T e r m i n a l . e c r i r e S t r i n g ( Quel e s t l e c o u v e r t maximal e a u t o r i s : ) ;
double max ;
max = T e r m i n a l . l i r e D o u b l e ( ) ;
c = new CompteAvecDecouvert ( Marie , num . t o C h a r A r r a y ( ) , 1 0 0 0 0 . 0 0 , max ) ;
}
System . o u t . p r i n t l n ( s o l d e a v a n t r e t r a i t
+ c . soldeCourant ( ) ) ;
try {
System . o u t . p r i n t l n ( T e n t a t i v e de r e t r a i t de 1 1 0 0 0 . 0 0 ) ;
c . r e t r a i t (11000.00);
System . o u t . p r i n t l n ( l e r e t r a i t c e s t b i e n p a s s e e ; nouveau s o l d e =
+ c . soldeCourant ( ) ) ;
CHAPITRE 16. HERITAGE
10
}
catch ( Exception e )
{ System . o u t . p r i n t l n ( Un p r o b l e m e e s t s u r v e n u l o r s du r e t r a i t ) ; }
}
}