0% ont trouvé ce document utile (0 vote)
72 vues17 pages

Solution Exercices

Transféré par

LOUNDOU orthega
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
72 vues17 pages

Solution Exercices

Transféré par

LOUNDOU orthega
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

5.

Solutions des exercices


45

Exercice 1.1
Donnez un exemple de fonctionnalité largement réutilisable.
Réponse : Parmi les fonctionnalités les plus répandues et pouvant être réutilisée dans les
applications actuelles l’authentification des utilisateurs d’une application ou d’un site Web.

Exercice 1.2
Quels sont les principaux nouveautés du modèle en spiral par rapport aux autres
modèles ?
Réponse : Le modèle spiral est un modèle complexe qui intègre pratiquement tous les
autres modèles de processus logiciels (prototypage, séquentiel ...etc). Sa nouveauté réside
dans le fait qu’il incorpore l’analyse des risques à chaque révolution de la spirale ce qui
constitue un excellent contrôle durant le processus de développement contre les risques de
natures divers (solution obsolète, logiciel développé déjà par un rival, besoin devenu non
impertinent ...etc).

Exercice 1.3
Dans le processus de développement par composants, que faire si on trouve pas de
composant qui assure une fonction donnée ?
Réponse : Dans le cas d’absence d’un composant adéquat pour un besoin donné on
procède comme suit :
1. On essaye tout d’abord de modifier, dans la mesure du possible, le besoin afin qu’il
coïncide avec un composant existant.
2. Dans le cas échéant, on créé le composant (par l’équipe de développement ou par
sous-traitance).
L’idée est de favoriser toujours la réutilisation qui est au cœur du développement par
composant.

Exercice 2.1
Donnez le code du plus petit programme en Java affichant le message « HelloWorld ».

1 / / f i c h i e r Main . j a v a
2 p u b l i c c l a s s Main {
3 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 [ ] ) {
4 System . o u t . p r i n t l n ( " H e l l o W o r l d " ) ;
5 }
6 }

Même l’affichage d’un message nécessite une classe principale et une méthode principale
main. Java est un langage purement orienté objet (on ne peut pas écrire du code en dehors
des classes).
46 Chapitre 5. Solutions des exercices

Exercice 2.2
Étant donné une classe java quelconque, on veut que cette classe soit directement
interprétable ( exécutable) par la JVM, que doit-on ajouter à cette classe ?
On doit ajouter à la classe la méthode principale : public static void main(String args[])
....
On peut instancier des objets de la classe dans la méthode main et invoquer les
différentes méthodes a titre de test. Dans une application Java constituée de plusieurs
classes on peut ajouter à chaque classe une méthode main et on peut interpréter cette classe
séparément des autres (pour test unitaire). Après les tests, on peut enlever les différentes
méthodes main et ne laisser qu’une seule pour l’application.

Exercice 2.3
Donnez le code d’une classe Java « First ». Ajoutez un constructeur par défaut à cette
classe qui affiche le message « Un Objet est créé » puis un destructeur qui affiche « Un
Objet est détruit ». Ajoutez une méthode principale à cette classe (main) dans laquelle
vous instanciez (créez) deux objets f1 et f2.

1 / / f i c h i e r F i r s t . java
2 public class First {
3 public First () {
4 System . o u t . p r i n t l n ( "Un O b j e t e s t c r é é " ) ;
5 }
6 public void f i n a l i z e ( ) {
7 System . o u t . p r i n t l n ( "Un O b j e t e s t d é t r u i t " ) ;
8 }
9 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 [ ] ) {
10 F i r s t f 1 =new F i r s t ( ) ;
11 F i r s t f 2 =new F i r s t ( ) ;
12 }
13 }

Q1) Comment détruire l’objet f1 ? Pour détruire un objet Java, il faut le « déréférencer
» i.e le nombre (compteur) de références à cet objet doit être 0. Dans notre cas (une seule
référence f1) il suffit de faire : f1=null ;
Q2) Comment faire pour s’assurer qu’à chaque destruction d’un objet le message du
destructeur s’affiche ?
Le ramasse-miettes gc (garbages-collector) de la JVM s’exécute en concurrence avec
nos applications, rien n’assure qu’il procède au nettoyage nécessaire au moment voulu
(lorsque on déréférence l’objet). Pour s’assurer que le gc exécute le destructeur de notre
classe (et par conséquent l’affichage) il faut l’invoquer manuellement par : [Link]() ; //
à exécuter après f1=null ;
Q3) On veut garder la trace du nombre d’objets de la classe « First » existant à chaque
instant en utilisant un compteur entier - Modifiez le code de la classe First en ajoutant une
méthode qui affiche à chaque fois la valeur du compteur d’objet

1 / / f i c h i e r F i r s t . java
2 public class First {
47

3 s t a t i c i n t nbObject ;
4 public First () {
5 System . o u t . p r i n t l n ( "Un O b j e t e s t c r é é " ) ;
6 n b O b j e c t ++ ;
7 }
8 public finalize () {
9 System . o u t . p r i n t l n ( "Un O b j e t e s t d é t r u i t " ) ;
10 nbObject − − ;
11 }
12 Public s t a t i c printnbObject () {
13 System . o u t . p r i n t l n ( " Nombre d ’ o b j e t s a c t i f s : "+nbObject ) ;
14 }
15 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 [ ] ) {
16 F i r s t f 1 =new F i r s t ( ) ; F i r s t . p r i n t n b O b j e c t () ;
17 F i r s t f 2 =new F i r s t ( ) ; F i r s t . p r i n t n b O b j e c t () ;
18 f1= n u l l ; F i r s t . p r i n t n b O b j e c t ( ) ;
19 System . gc ( ) : F i r s t . p r i n t n b O b j e c t ( ) ;
20 }
21 }

Q4 (à documenter par l’étudiant) Parmi les fonctionnalités (rôles) des constructeurs d’une
classe l’initialisation des attributs d’instance (objets). Existe-t-il une méthode pour initiali-
ser les attributs de classe ?
Réponse : Oui, Comme pour les attributs d’instances, on peut inclure un Constructeur
de classe dont le rôle est l’initialisation des attributs de classe. Syntaxe : static. . . . . . . . . //
ceci est un bloc d’instructions constituant le constructeur static de la // classe

Exercice 2.4
Q1) Donner le code Java de la classe Cercle avec :
Attributs : double rayon ;
Méthodes :

— Cercle() ;
— Cercle(double nR) ;
— double getSurface() ;
— double getPerimetre() ;
— void setRaon(double nR) ;
Solution :

1 public class Cercle {


2 double rayon ;
3 public Cercle () {
4 rayon =1;
5 }
6 p u b l i c Cercle ( double rayon ) {
7 / / t h i s r e p r é s e n t e une r é f é r e n c e de l ’ o b j e t en c o u r s ,
o b l i g a t o i r e de l ’ u t i l i s e r d a n s l e c a s de c h e v a u c h e m e n t e n t r e l e nom
de l ’ a t t r i b u t e t l e nom du param è t r e f o r m e l
8 t h i s . rayon = rayon ;
9 }
48 Chapitre 5. Solutions des exercices

10 public double getSurface ( ) {


11 r e t u r n r a y o n * r a y o n * Math . P I ;
12 }
13 public double getPerimetre ( ) {
14 r e t u r n 2 * r a y o n * Math . P I ;
15 }
16 }

a) Ecrire une Méthode principale main dans Cercle qui utilise la classe Cercle pour
créer 3 objets (cercle1,cercle2 et cercle3) ayants respectivement les rayons 1, 25 et 125 et
permettre d’afficher le périmètres et la surface de chacun des trois objets Cercle. Ensuite, le
programme change le rayon du second avec la valeur 100 et affiche son rayon et sa surface.

1 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 [ ] ) {
2 C e r c l e c e r c l e 1 =new C e r c l e ( ) ;
3 System . o u t . p r i n t l n ( " La s u r f a c e du c e r c l e a y a n t l e rayon="+ c e r c l e 1 .
rayon+" e s t : "+ cercle1 . getSurface ()+ " e t son pé rim è t r e
e s t : "+ c e r c l e 1 . g e t P e r i m e t r e ( ) ) ;
4 C e r c l e c e r c l e 2 =new C e r c l e ( 2 5 ) ;
5 System . o u t . p r i n t l n ( " La s u r f a c e du c e r c l e a y a n t l e rayon="+ c e r c l e 2 .
rayon+" e s t : "+ cercle2 . getSurface ()+ " e t son pé rim è t r e
e s t : "+ c e r c l e 2 . g e t P e r i m e t r e ( ) ) ;
6 C e r c l e c e r c l e 3 =new C e r c l e ( 1 2 5 ) ;
7 System . o u t . p r i n t l n ( " La s u r f a c e du c e r c l e a y a n t l e rayon="+ c e r c l e 2 .
rayon+" e s t : "+ cercle2 . getSurface ()+ " e t son pé rim è t r e
e s t : "+ c e r c l e 2 . g e t P e r i m e t r e ( ) ) ;
8 }

b) Pour détruire les objets de la classe Cercle, un programmeur a ajouter la méthode


suivante dans la classe Cercle :

1 public s t a t i c void d e t r u i r e ( Cercle c ) {


2 c= n u l l ;
3 }

Et dans la méthode main il a ajouté l’instruction :

1 Cercle . d e t r u i r e ( c e r c l e 1 ) ; / / pour dé t r u i r e l e premier o b j e t

La méthode ajoutée va-t-elle détruire effectivement l’objet cercle1 ? justifiez votre réponse.

Réponse : Non la méthode ne détruira pas l’objet cercle1. En java, le seul mode
de passage des paramètres est le passage par valeur, la référence passée à la méthode
detruire(. . . ) sera dupliquée, la méthode affecte la valeur null à la copie dupliquée de la
référence. Après l’exécution de la méthode détruire l’objet cercle1 restera toujours en vie
(non null).
49

Exercice 2.5
Dans un fichier [Link] définissez la classe Fleur de sorte que le programme
principal suivant :

1 p u b l i c c l a s s Poeme {
2 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 ) {
3 F l e u r f 1 = new F l e u r ( " V i o l e t t e " , " b l e u " ) ;
4 F l e u r f 2 = new F l e u r ( f 1 ) ;
5 System . o u t . p r i n t ( " d a n s un c r i s t a l " ) ;
6 f2 . e c l o r e ( ) ;
7 System . o u t . p r i n t ( " ne l a i s s a n t p l u s " ) ;
8 System . o u t . p r i n t l n ( f 1 ) ;
9 System . o u t . p r i n t l n ( f 2 ) ;
10 }
11 }

affiche le texte suivant :


Violette fraichement cueillie
Fragile corolle taillée dans un cristal veiné de bleu
ne laissant plus qu’un simple souffle
qu’un simple souffle

Solution : En analysant le texte à afficher :

— La classe Fleur doit comporter deux attributs ; nom et couleur


— Le constructeur de la classe Fleur doit afficher l’attribut nom suivi de "fraichement
cueillie" dans une première ligne et "Fragile corolle taillée" dans une deuxième
ligne.
— La classe Fleur doit comporter une méthode eclore() qui affiche «le texte « veiné de
» suivi de l’attribut couleur.
— La conversion d’un objet de la classe Fleur en une chaine de caractère doit donner la
chaine "qu’un simple souffle" pour que print(f1) et print(f2) puisse donner l’affichage
désiré. La conversion se fait par une méthode toString héritée de la classe Object à
redéfinir dans Fleur
— La classe doit inclure un constructeur par copie (on lui passant un objet comme
paramètre il crée une copie identique à ce dernier (appelé clone).
Selon les spécifications précédentes le code de la classe Fleur est le suivant :

1 public class Fleur {


2 S t r i n g nom ;
3 String color ;
4 p u b l i c F l e u r ( S t r i n g nom , S t r i n g c o l o r ) {
5 t h i s . nom=nom ;
6 this . color=color ;
7 System . o u t . p r i n t l n ( nom+ " f r a i c h e m e n t c u e i l l i e " ) ;
8 System . o u t . p r i n t ( " F r a g i l e c o r o l l e t a i l l é e " ) ;
9 }
10 public Fleur ( Fleur clone ) {
11 t h i s . nom= c l o n e . nom ;
12 t h i s . color=clone . color ;
50 Chapitre 5. Solutions des exercices

13 }
14 public void e c l o r e ( ) {
15 System . o u t . p r i n t l n ( " v e i n é de " + t h i s . c o l o r ) ;
16 }
17 @ o v e r r i d e / / a n n o t a t i o n de l a r e d é f i n i t i o n d e s mé t h o d e s
18 public String toString () {
19 r e t u r n " qu ’ un s i m p l e s o u f f l e " ;
20 }
21 }

Exercice 2.6
Une Voiture est constitué de :
— un Chassis (caractérisé par un numéro de série)
— une Carosserie (caractérisée par son type : sport, berline, citadine)
— un Habitacle (caractérisé par le nombre de portes 02 ou 04)
— un Moteur (caractérisé par sa capacité en litre,puissance en nombre de chevaux et
type d’énergie (Essence,Gas-oil ou GPL-C))
— une Boite de vitesse (caractérisé par type : manuelle/Automatique et le nombre de
rapport 5,6 ..).
— 04 Roues
— 04 ou 02 Portes selon le type de carosserie (AV-G,AV-D,AR-G,AR-D) et
— 04 Optiques
Q1) Proposez le code Java correspondant aux différentes classes nécessaires à la modélisa-
tion de l’énoncé de cet exercice.

1 public Class Voiture {


2 C h a s s i s ch
3 Carosserie cr ;
4 H a b i t a c l e hb ;
5 Moteur mt ;
6 Boite bt ;
7 Roue r a g , r a d , r r g , r r d ;
8 i n t nbPorte ;
9 O p t i q u e opag , opad , oprg , o p r d ;
10 }

1 public class Chassis {


2 private int nSerie ;
3 p u b l i c C h a s s i s ( ns ) { n s e r i e =ns ; }
4 }

1 public class Carosserie {


2 private String crtype ;
3 public Carosserie ( String t ) { crtype=t ;}
4 }
51

1 Public class Habitacle {


2 i n t nbPorte ;
3 public Habitacle ( in nbPorte ) {
4 i f ( ( n b P o r t e ==2) | | ( n b P o r t e ==4) )
5 t h i s . n b P o r t e = n b P o r t e ; e l s e n b P o r t e =4 ;
6 }
7 }

1 p u b l i c c l a s s Moteur {
2 float capacite ;
3 i n t nbChevaux ;
4 String energie ;
5 p u b l i c Moteur ( f l o a t c , i n t ch , S t r i n g en ) {
6 c a p a c i t e =c ; nbChevaux = ch ; e n e r g i e = en ;
7 }
8 }

1 public class Boite {


2 char typeBoite ;
3 i n t nbRapports ;
4 p u b l i c B o i t e ( char tb , i n t nbr ) {
5 t y p e B o i t e = ’m’ ; / / par dé f a u t
6 i f ( t b = ’ a ’ ) t y p e B o i t e = ’m’ ;
7 i f ( nbr >=5) { n b R a p p o r t s = n b r ; }
8 }
9 }

1 Public c l a s s Optique {
2 // ...
3 }

Q2) Dans le langage Java On peut déclarer des classes à l’intérieur d’une classe (les
inner-classes) mais cette pratique est très rares et déconseillée, et il est toujours suggérer
de déclarer séparément les classes. A votre avis pourquoi ?
Réponse : les inner-classes présentent les inconvénients suivants :

1. Difficulté de réutilisation de telles classes


2. Conception ambigüe due à l’imbrication du code de ces classes dans d’autres classes

Exercice 2.7
Dans l’exercice 4 (classe Cercle) Comment peut-on éviter des valeurs négatives ou
nulles pour l’attribut Rayon ?
52 Chapitre 5. Solutions des exercices

Réponse : en encapsulant l’attribut rayon par :

1 p r i v a t e double rayon ;
2 p u b l i c void setRayon ( double rayon ) {
3 i f ( rayon >0) t h i s . rayon = rayon ;
4 }
5 p u b l i c double getRayon ( ) {
6 r e t u r n rayon ;
7 }

Exercice 2.8
Un objet Robot qui a deux vitesses (gauche et droite). Il peut avancer en avant (ou
reculer en arrière) quand ses deux vitesses sont égales et positives (négatif respectivement).
Comme il peut tourner vers la gauche (ou la droite) si les 2 vitesses sont différentes dans le
sens de la vitesse la plus grande. Il peut aussi freiner si les deux vitesses tendent vers le 0.
Essayez de répondre aux questions suivantes :
Q1) Comment peut-on empêcher le blocage des roues ? Empêcher que vitG=vitD=0 pour
ne pas avoir un freinage brutal ;
Q2) Comment empêcher l’inversion brutale du sens de rotation des moteurs ?
Q3) comment éviter de casser la mécanique (il marche en avant et on lui demande d’aller
directement en arrière son freinage en changeant ses deux vitesses en valeurs négatives) ?
Q4) Comment éviter un virage trop serré qui remettrait en cause la stabilité de la trajectoire
et éviter un renversement.
Donnez le code java de la classe Robot en implémentant les solutions proposées comme
réponses aux questions ci-dessus.

F IGURE 5.1 – Schéma du robot (données et méthodes)à programmer

Réponse : La solution consiste à empêcher la modification directe de l’état du robot,


il faut utiliser plutôt les méthodes (avancer, tourner, . . . ) dont le développeur respectera les
conditions imposées au mouvement du robot.
Les règles d’accès à l’état d’un objet sont indispensables pour éviter les mauvaises utilisa-
tions et sont implémentées grâce au mécanisme d’encapsulation.
53

Code java de la solution :

1 import java . io . * ; / / pour l a f o n t i o n s l e e p ( )


2 p u b l i c c l a s s Robot {
3 // attributs :
4 p r i v a t e double vitG , vitD ;
5 p r i v a t e b o o l e a n sensG , sensD ;
6 p r i v a t e f l o a t vitMax =100;
7 / / mé t h o d e s :
8 p u b l i c Robot ( ) {
9 vitG = 0 . 1 ; vitD = 0 . 1 ; / / v i t e s s e tende vers le 0
10 sensG = t r u e ; sensD = t r u e ;
11 }
12
13 public void avancer ( double v ) {
14 i f ( ( v i t D < 0 )&& ( v i t G < 0 ) ) / / s ’ i l marche en a r r i è r e ne p e u t
p a s a v a n c e r en a v a n t
15 System . o u t . p r i n t l n ( " v o u s d e v e z f r e i n e r a v a n t d ’ a v a n c e r en
avant " ) ;
16 else {
17 / / v é r i f i e r s i l a v i t e s s e d ’ a v a n c e m e n t n ’ e s t p a s n é g a t i v e ou
s u p é r i e u r à l a v i t e s s e max
18 i f ( v >0 && v < v i t M a x ) {
19 vitG = v ; vitD = v ;
20 sensG = t r u e ; sensD = t r u e
21 System . o u t . p r i n t l n ( " j ’ a v a n c e " ) ;
22 } else {
23 System . o u t . p r i n t l n ( " j e r e s t e en é t a t a v a n c é " ) ;
24 }
25 }
26 }
27 p u b l i c v o i d t o u r n e r ( b o o l e a n sensG , b o o l e a n sensD ) {
28 i f ( sensG == sensD )
29 System . o u t . p r i n t l n ( " v o u s d e v e z s p é c i f i e r l e s e n s de
d i r e c t i o n pour t o u r n e r " ) ;
30 else {
31 t h i s . sensD = sensD ;
32 t h i s . sensG = sensG ;
33 i f ( sensG == t r u e&&sensD == f a l s e ) { / / t o u r n e r v e r s l a
gauche
34 vitD = vitD − 1; vitG = vitG + 1; // vitesse
gauche > v d r o i t e
35 } else { / / tourner vers la droite
36 vitD = vitD + 1; vitG = vitG − 1; // vitesse
d r o i t e > v gauche
37 }
38 }
39 }
40
41 public void r e c u l e r ( double v ) {
42 / / s i l e s deux v i t e s s e s ne t e n d e n t p a s v e r s l e 0 on ne p e u t p a s
reculer
43 i f ( ( v i t D ! = 0 . 1 )&& ( v i t G ! = 0 . 1 ) )
44 System . o u t . p r i n t l n ( " v o u s d e v e z f r e i n e r a v a n t de r e c u l e r en
54 Chapitre 5. Solutions des exercices

a r r i è re " ) ;
45 else {
46 / / s ’ i l e s t en é t a t a r r i è r e ou é t a t f r e i n e r
47 i f ( v i t D <0 &&v i t G < 0 ) | | ( v i t D = = 0 . 1 &&v i t G = = 0 . 1 ) {
48 i f ( v >0 && v < v i t M a x ) {
49 / / l e s deux v i t e s s e s d o i v e n t ê t r e n é g a t i v e s
50 vitG = v* ( −1) ; vitD = v *( −1) ;
51 sensD = f a l s e ; sensG = f a l s e ; / / sensG e t
sensD d o i v e n t ê t r e f a l s e
52 System . o u t . p r i n t l n ( " j e r e c u l e " ) ;
53 } else {
54 System . o u t . p r i n t l n ( " j e r e s t e en é t a t r e c u l e r "
);
55 }
56 }
57 }
58 }
59 public void F r e i n e r ( ) {
60 i f ( v i t G < 0 ) &&(v i t D < 0 ) { / / d a n s l e c a s o ù i l marche en a r r i è
re et veut f r e i n e r
61 vitG = vitG *( −1) ; vitD = vitD *( −1) ;
62 }
63 / / d i m i n u e r l e s v i t e s s e s p r o g r e s s i v e m e n t ( en 3 é t a p e s ) j u s q u ’ à 0
64 d o u b l e kG = v i t G / 3 ; v i t G = v i t G −kG ;
65 d o u b l e kD = v i t D / 3 ; v i t D = v i t D −kD ;
66 / / a t t e n d r e 15 s e c o n d e s en u t i l i s a n t T h r e a d . s l e e p ( ms ) ( c h i f f r e
en m i l l i s e c o n d e s )
67 try {
68 Thread . s l e e p (15000) ;
69 } c a t c h ( E x c e p t i o n ex ) { System . o u t . p r i n t ( ex ) ; }
70 v i t G = v i t G − kG ; v i t D = v i t D −kD ;
71 / / a t t e n d r e p e n d a n t une d e u x i ème d u r é e de 15 s e c o n d e s
72 try {
73 Thread . s l e e p (15000) ; / / s u s p e n d r e l ’ ex é c u t i o n 15 s une
d e u x i ème f o i s
74 } c a t c h ( E x c e p t i o n ex ) { System . o u t . p r i n t ( ex ) ; }
75 vitG = 0.1 ; vitD = 0 . 1 ; / / tendent vers le 0
76 System . o u t . p r i n t l n ( " j ’ a i f r e i n é " ) ;
77 }
78 p u b l i c s s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
79 Robot R1=new Robot ( ) ;
80 R1 . a v a n c e r ( 2 0 ) ;
81 R1 . r e c u l e r ( 1 0 ) ;
82 R1 . F r e i n e r ( ) ;
83 R1 . r e c u l e r ( 1 0 ) ;
84 R1 . a v a n c e r ( 1 5 ) ;
85 }
86 }

Exercice 2.9
Une image est modélisée par son nombre de lignes (nl), de colonnes (nc) et une matrice
(matc) contenant des entiers représentant les valeurs d’intensité de la couleur à chaque
55

case (i,j) de la matrice. Donnez le code de la classe Image en proposant un constructeur


avec deux paramètres (lignes, colonnes).

1 p u b l i c c l a s s Image {
2 i n t n l , nc ;
3 i n t [ ] [ ] matc ;
4 p u b l i c Image ( i n t n l , i n t nc ) {
5 t h i s . nl=nl ;
6 t h i s . nc = nc ;
7 matc =new i n t [ n l ] [ nc ] ;
8 }
9 }

Sachant que le nombre de lignes et de colonnes d’un objet image ne changent pas, proposez
une encapsulation adéquate à ces attributs.

1 p u b l i c c l a s s Image {
2 p r i v a t e i n t n l , nc ;
3 p r i v a t e i n t [ ] [ ] matc ;
4 p u b l i c Image ( i n t n l , i n t nc ) {
5 t h i s . nl=nl ;
6 t h i s . nc = nc ;
7 matc =new i n t [ n l ] [ nc ] ;
8 }
9 public i n t getNl ( ) { r e t u r n nl ;}
10 p u b l i c i n t g e t N c ( ) { r e t u r n nc ; }
11 }

Un accesseur en modification (setter) pour l’attribut matc est défini par

1 public void setMatc ( i n t [ ] [ ] m) { matc =m ; }

Discutez les risques liés à ce type d’accesseur et proposez un autre accesseur ne pré-
sentant pas les mêmes risques. Réponse : Les risques liés à ce type d’accesseur réside
dans le fait que l’utilisateur remplace directement la matrice contenant les données de
l’image par une autre et par conséquent il peut mettre des données erronées dans cette
matrice, à titre d’exemple il peut mettre une matrice de dimension différente (nombre
de lignes et de colonnes ne correspondent pas à nl et nc). Une solution consiste à don-
ner l’accès à l’utilisateur de modifier juste une case de la matrice avec la nouvelle méthode :

1 public void setMat ( i n t i , i n t j , i n t val ) {


2 i f ( ( i * j ! = 0 ) && ( i < n l ) && ( j < nc ) ) matc [ i ] [ j ] = v a l ;
3 }

R c’est cette méthode qui est préconisée dans le standard JavaBeans pour l’encapsulation
des attributs indexés (tableaux . . . ). L’accesseur Setter modifie chaque élément indexé
séparément.
56 Chapitre 5. Solutions des exercices

Exercice 2.10
Donnez le code Java de la classe TV avec :
Attributs :
— on :boolean
— chaine : int (>0 et <9999)
— volume int (>=0 et <=10)
Méthodes :
— void allumer() // mettre on à true
— void eteindre() // mettre on à false
— void setChaine(int ch) // change de chaine,
— void chaineUp() //aller à la chaine suivante,
— void chaineDown() // aller à la chaine précédente
— void volumeUp() // augmente le volume +1
— void volumeDown() //diminue le volume -1
— void reCall () // affiche la liste des 4 dernière chaines regardées

R les différentes opérations ne doivent opérer que si la TV est allumée.

1 p u b l i c c l a s s TV {
2 i n t chaine =1;
3 i n t volume = 1 ;
4 b o o l e a n on= f a l s e ;
5 i n t ch1 =1 , ch2 =1 , ch3 =1 , ch4 =1 / / p o u r l a l i s t e r e C a l l ;
6 / / Les d i f f é r e n t e s i n i t i a l i s a t i o n s é t a n t f a i t e s , on n ’ a p a s b e s o i n
d ’ un c o n s t r u c t e u r , l e
7 / / C o m p i l a t e u r i n s è r e a u t o m a t i q u e m e n t un c o n s t r u c t e u r v i d e
8 p u b l i c v o i d a l l u m e r ( ) { i f ( ! on ) on= t r u e ; }
9 p u b l i c v o i d e t e i n d r e ( ) { i f ( on ) on= f a l s e ; }
10 p u b l i c v o i d s e t C h a i n e ( i n t ch ) { i f ( on && ( c h a i n e >=1) && ( c h a i n e
< 9 9 9 9 ) && ( ch ! = c h a i n e ) )
11 c h a i n e = ch ;
12 ch1 = ch2 ; ch2 = ch3 ; ch3 = ch4 ; ch4 = c h a i n e ;
13 }
14 p u b l i c void chaineUp ( ) {
15 i f ( on )
16 i f ( chaine <9999)
17 c h a i n e ++;
18 else
19 chaine =1;
20 ch1 = ch2 ; ch2 = ch3 ; ch3 = ch4 ; ch4 = c h a i n e ;
21 }
22 p u b l i c v o i d chaineDown ( ) {
23 i f ( on )
24 i f ( chaine >1)
25 c h a i n e − −;
26 else
27 c h a i n e =9999;
28 ch1 = ch2 ; ch2 = ch3 ; ch3 = ch4 ; ch4 = c h a i n e ;
29 }
30 p u b l i c v o i d volumeUp ( ) {
31 i f ( on )
57

32 i f ( volume < 1 0 ) volume ++;


33 }
34 p u b l i c v o i d volumeDown ( ) {
35 i f ( on )
36 i f ( volume > 0 )
37 volume − −;
38 }
39 public void r e C a l l ( ) {
40 System . o u t . p r i n t l n ( ch4 + " , " + ch3 + " , " + ch2 + " , " + ch1 ) ;
41 }
42 }

Exercice 3.1
Soit la classe Java Suivante :

1 public class Pixel {


2 int x ;
3 int y ;
4 }

1. Proposez un constructeur paramétré à la classe précédente


2. Encapsulez les attributs x et y de cette classe
3. A partir de la classe précédente, on veut construire la classe "ColoriedPixel" des
pixels coloriés. Proposez une implémentation de cette classe avec son constructeur.

R La couleur est un tableau de 3 valeurs entières (dans le plan RGB).

Solution :

1.
1 public class Pixel {
2 int x ;
3 int y ;
4 public Pixel ( int x , int y) {
5 this . x=x ;
6 this . y=y ;
7 }
8 }

1 public class Pixel {


2 private int x ;
3 private int y ;
4 public Pixel ( int x , int y) {
5 this . x=x ;
6 this . y=y ;
7 }
58 Chapitre 5. Solutions des exercices

8 public void setX ( int x) { this . x=x ; }


9 public i n t getX ( ) { return this . x ;}
10 public void setY ( int y) { this . y=y ; }
11 public i n t getY ( ) { return this . y ;}
12 }

3.
2.
1 public class ColoriedPixel extends Pixel {
2 i n t color []= {0 ,0 ,0} ;
3 public ColoriedPixel ( int x , int y){
4 s u p e r ( x , y ) ; / / a p p e l au s u p e r − c o n s t r u c t e u r o b l i g a t o i r e c a u s e :
c e d e r n i e r e s t a v e c param è t r e s
5 f o r ( i =0 ; i < c o l o r . l e n g t h ; i ++)
6 c o l o r [ i ]=0 ;
7 }
8 }

4. — Première variante :

1 public class ColoriedPixel extends Pixel {


2 int color [] ;
3 public ColoriedPixel ( int x , int y){
4 s u p e r ( x , y ) ; / / a p p e l au s u p e r − c o n s t r u c t e u r o b l i g a t o i r e
c a u s e : c e d e r n i e r e s t a v e c param è t r e s
5 f o r ( i =0 ; i < c o l o r . l e n g t h ; i ++)
6 c o l o r [ i ]=0 ;
7 }
8 public void setColor ( i n t color [ ] ) { t h i s . color = color ;}
9 public int [] getColor () { return t h i s . color }
10 }

Inconvénient : lorsqu’il s’agit d’un attribut indexé (contenant plusieurs éléments


tels que les tableaux, listes ...etc) la manipulation de attribut en entier peut
affecter le principe d’encapsulation comme dans l’exemple suivant :
Soit le code qui utilise la classe ColoriedPixel précédente :

1 C o l o r i e d P i x e l cp =new C o l o r i e s P i x e l ( 1 , 2 ) ;
2 i n t t c [ ] = cp . g e t C o l o r ( ) ;
3 t c [ 0 ] = 1 0 0 ; / / a c c è s d i r e c t à l ’ a t t r i b u t c o n t r a i r e au p r i n c i p e
d ’ encapsulation

— Deuxième variante (solution qui respecte mieux le principe d’encapsulation) :

1 public class ColoriedPixel extends Pixel {


2 int color [] ;
3 public ColoriedPixel ( int x , int y){
4 s u p e r ( x , y ) ; / / a p p e l au s u p e r − c o n s t r u c t e u r o b l i g a t o i r e
c a u s e : c e d e r n i e r e s t a v e c param è t r e s
5 f o r ( i =0 ; i < c o l o r . l e n g t h ; i ++)
59

6 c o l o r [ i ]=0 ;
7 }
8 p u b l i c void s e t C o l o r ( i n t index , i n t value ) { i f ( index < t h i s .
c o l o r . l e n g t h ) t h i s . c o l o r [ index ]= v a l u e ; }
9 p u b l i c i n t g et Co lo r ( i n t index ) { i f ( index < t h i s . c o l o r . l e n g t h )
r e t u r n t h i s . color [ index ] ;}
10 }

Exercice 3.2
— Donnez le code Java d’une classe nommé « Segment » contenant deux attributs
encapsulés de type de la classe précédente ColoriedPixel (exercice 3.1).
— On veut construire maintenant la classe des rectangles de 2 manières :
— La première par héritage de la classe Segment
— La deuxième par composition (la classe comporte deux attributs objets de la
classe Segment).
Donnez le code des deux variantes.
— Quelle est la meilleure implémentation à votre avis.
1.
1 p u b l i c c l a s s Segment {
2 p r i v a t e C o l o r i e d P i x e l px1 ;
3 p r i v a t e C o l o r i e d P i x e l px2 ;
4 p u b l i c Segment ( i n t x1 , i n t y1 , i n t x2 , i n t y2 ) {
5 px1=new C o l o r i e d P i x e l ( x1 , y1 ) ;
6 px2=new C o l o r i e d P i x e l ( x2 , y2 ) ;
7 }
8 p u b l i c Segment ( C o l o r i e d P i x e l px1 , C o l o r i e d P i x e l px2 ) {
9 t h i s . px1=px1 ;
10 t h i s . px2=px2 ;
11 }
12 public void setPx1 ( i n t x , i n t y , i n t [] color ) {
13 px1 . s e t X ( x ) ; px1 . s e t Y ( y ) ;
14 i f ( c o l o r . l e n g t h ==3)
15 f o r ( i n t i =0 ; i < c o l o r . l e n g t h ; i ++)
16 px1 . s e t C o l o r ( i , c o l o r [ i ] ) ;
17 }
18 p u b l i c C o l o r i e d P i x e l g e t P x 1 ( ) { r e t u r n t h i s . px1 ; }
19 public void setPx2 ( i n t x , i n t y , i n t color [ ] ) {
20 px2 . s e t X ( x ) ; px2 . s e t Y ( y ) ;
21 i f ( c o l o r . l e n g t h ==3)
22 f o r ( i n t i =0 ; i < c o l o r . l e n g t h ; i ++)
23 px2 . s e t C o l o r ( i , c o l o r [ i ] ) ;
24
25 }
26 p u b l i c v o i d C o l o r i e d P i x e l g e t P x 2 ( ) { r e t u r n t h i s . px2 ; }
27 }

2/
— 1ère Variante (Héritage) ;
60 Chapitre 5. Solutions des exercices

1 p u b l i c c l a s s R e c t a n g l e e x t e n d s Segment {
2 / / px1 e t px2 s o n t h é r i t é s de l a c l a s s e Segment
3 p r i v a t e C o l o r i e d P i x e l px3 ;
4 p r i v a t e C o l o r i e d P i x e l px4 ;
5 p u b l i c R e c t a n g l e ( C o l o r i e d P i x e l px1 , C o l o r i e d P i x e l px2 ,
C o l o r i e d P i x e l px3 , C o l o r i e d P i x e l px4 ) {
6 s u p e r ( px1 , px2 ) / / a p p e l au s u p e r c o n s t r u c t e u r p o u r
i n i t i a l i s e r l e s a t t r i b u t s px1 e t px2
7 t h i s . px3=px3 ;
8 t h i s . px4=px4 ;
9 }
10 / / à compl é t e r p a r l e s a c c e s s e u r s de px3 e t px 4 de l a même
mani è r e que d a n s Segment p o u r px1 / / e t px2
11 }

— 2eme variante (agrégation) :

1 public class Rectangle {


2 p r i v a t e Segment s g 1 ;
3 p r i v a t e Segment s g 2 ;
4 p u b l i c R e c t a n g l e ( C o l o r i e d P i x e l px1 , C o l o r i e d P i x e l px2 ,
C o l o r i e d P i x e l px3 , C o l o r i e d P i x e l px4 ) {
5 s g 1 =new Segment ( px1 , px2 ) ;
6 s g 2 =new Segment ( px3 , px4 ) ;
7 }
8
9 / / compl é t e r p a r l e s a c c e s s e u r s n é c e s s a i r e s p o u r m o d i f i e r l e s
d i f f é r e n t e s v a l e u r s de s g 1 e t s g 2
10 }

Exercice 3.3
Quels sont les avantages et les inconvénients des deux types d’invocation des méthodes
statique et dynamique ?
Avantages Inconvénients

Réponse : Liaison statique exécution rapide, liaison faite au mo- - ne permet pas d’invoquer la mé-
ment de l’édition de lien thode du type courant de l’objet
Liaison dynamique permet l’invocation du type courant exécution lente

Vous aimerez peut-être aussi