Java
Java
Java
*+, -./
0%12345 6#$$71
8 9/. :/
;#$$71<1#$#47=:>%23?1#4@AB2
l
C%;$# D#? =%13E2#?
-A *+CFGHI8C*G+ J "KGF*L+CM G6(LC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -
-A-A "LN G6(L8C*,N HLN 8GIFN HK*+,GFOPC*QIL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -
-A9A "P 8P"8I"P6*"*CM AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -
-A/A "KGFH*+PCLIF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9
-ARA "LN 0FGSFPOOLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /
1.4.1. LA NEN0IRE RAN ...................................................................................................................................................... S
1.4.2. LES B0NNEES B'0N PR0uRANNE ............................................................................................................................. S
1.4.S. LA BASE BES PR0uRANNES ....................................................................................................................................... S
1.4.4. L'INvENTI0N BES LANuAuES BE PR0uRANNATI0N ............................................................................................. 4
1.4.S. LES PARABIuNES BE PR0uRANNATI0N .................................................................................................................. 4
1.4.6. LA PR0uRANNATI0N INPERATIvE ........................................................................................................................... 4
-ATA "P 0FGSFPOOPC*G+ GF*L+CM G6(LC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA R
-AUA "L 8PN HLN *+CLF,P8LN SFP0V*QILN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA T
1.6.1. ARCBITECT0RE BES 0B}ETS ....................................................................................................................................... 6
1.6.2. CASCABE BE NESSAuES .............................................................................................................................................. 7
1.6.S. LES NETB0BES ............................................................................................................................................................. 9
1.6.4. BE0X PRINCIPES ........................................................................................................................................................... 9
1.6.S. LE FL0T B'EXEC0TI0N ................................................................................................................................................ 9
-AWA 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -.
-AXA P 0FG0GN HL (PYP AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -.
-AZA P 0FG0GN HI 8GIFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --
9A 6PNLN HL "P 0FGSFPOOPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/
9A-A I+L 8"PNNL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/
9A9A I+L YPF*P6"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/
9A/A 8FMPC*G+ HKI+ G6(LC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -R
9ARA *+*C*P"*NPC*G+ HLN G6(LCN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -R
9ATA P,,*8VLF "LN PCCF*6ICN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -T
9AUA FLCGIF NIF "K*+*C*P"*NPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -U
9AWA I+ HLI[*\OL 8G+NCFI8CLIF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -W
9AXA I+ 8G+NCFI8CLIF QI* P00L""L I+ PICFL 8G+NCFI8CLIF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -X
9AZA "LN C]0LN L+ (PYP AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -X
9A-.A "LN C]0LN N8P"P*FLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -X
2.1u.1. LES 0PERATI0NS ARITBNETIQ0ES ...................................................................................................................... 19
2.1u.2. LES 0PERATE0RS BE C0NPARAIS0N ................................................................................................................... 2u
2.1u.S. LES 0PERATE0RS L0uIQ0ES .................................................................................................................................. 2u
9A--A "LN C]0LN FM,MFL+8LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9.
2.11.1. ENv0I BE NESSAuE ................................................................................................................................................. 21
2.11.2. SYNTAXE BES NETB0BES ...................................................................................................................................... 22
9A-9A "KL+8P0NI"PC*G+ HLN PCCF*6ICN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 99
2.12.1. LES ACCESSE0RS 00 NETB0BES B'ACCES ........................................................................................................... 2S
2.12.2. LES N0TATE0RS 00 NETB0BES BE N0BIFICATI0N ......................................................................................... 24
2.12.S. L'ENCAPS0LATI0N BES B0NNEES ........................................................................................................................ 2S
2.12.4. ENCAPS0LATI0N : vALIBER LES vALE0RS BES ATTRIB0TS ............................................................................. 2S
2.12.S. ENCAPS0LATI0N : C0BERENCE BES B0NNEES .................................................................................................. 26
2.12.6. ENCAPS0LATI0N : C0BERENCE BE L'APPLICATI0N .......................................................................................... 26
2.12.7. ENCAPS0LATI0N : TRANSPARENCE BES NISES EN 00vRE .............................................................................. 27
9A-/A "L OGC 8"M CV*N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9X
ll
9A-RA 0GFCML HLN HM8"PFPC*G+N HL YPF*P6"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9Z
9A-TA FLCGIF NIF "L OGC 8"M CV*N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9Z
9A-UA 0PNNPSL HL 0PFPO\CFLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /.
2.16.1. EXENPLE BE PASSAuE BE TYPES SCALAIRES ...................................................................................................... S1
2.16.2. EXENPLE BE PASSAuE BE TYPES REFERENCES .................................................................................................. S2
9A-WA 6"G8N HK*+NCFI8C*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /9
9A-XA YPF*P6"LN "G8P"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA //
9A-ZA FLCGIF NIF "KMSP"*CM AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA //
9A9.A 8G+YL+C*G+N HL +GOOPSL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA //
/A HLI[ 8"PNNLN 0FMHM,*+*LN^ "LN CP6"LPI[ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /T
/A-A "LN 8PFP8C\FLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /T
/A9A "LN 8VP_+LN HL 8PFP8C\FLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /U
/A/A L8F*FL HP+N "P 8G+NG"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /X
/ARA "KG0MFPCLIF ` HL 8G+8PCM+PC*G+ HL 8VP_+LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /X
/ATA "P HG8IOL+CPC*G+ (PYP AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /Z
/AUA "P 8"PNNL PFFP]"*NC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA /Z
/AWA "LN CP6"LPI[ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA R.
/AXA "LN 8"PNNLN 0FMHM,*+*LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA R-
RA 0FGSFPOOLF "LN OMCVGHLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA R/
RA-A "LN C]0LN HK*+NCFI8C*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA R/
RA9A "LN YPF*P6"LN "G8P"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RR
RA/A P,,L8CPC*G+ HKI+L YPF*P6"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RR
RARA "LN 8GOOL+CP*FLN HP+N "LN 0FGSFPOOLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RR
RATA "P 8"PNN 6P+aP88GI+C AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RT
RAUA "K*+NCFI8C*G+ FLCIF+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RU
RAWA 6"G8N HK*+NCFI8C*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RW
RAXA "P 8"PNNL 6P+a AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RW
RAZA FL8VLF8VL HKI+ 8GO0CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RW
4.9.1. L'INSTR0CTI0N C0NBITI0NNEL IF ......................................................................................................................... 48
4.9.2. L'0SAuE PARTIC0LIER BE L'INSTR0CTI0N IF ........................................................................................................ 48
RA-.A 0PF8GIF*F "P CP6"L HLN 8GO0CLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RX
4.1u.1. LES ELENENTS B'0NE ARRAYLIST ....................................................................................................................... 49
4.1u.2. L'INSTR0CTI0N ALTERNATIvE IF ......................................................................................................................... 49
4.1u.S. L'INSTR0CTI0N WBILE ........................................................................................................................................... Su
4.1u.4. L'INSTR0CTI0N B'ITERATI0N F0R ....................................................................................................................... Su
4.1u.S. LES ITERATE0RS ...................................................................................................................................................... S2
RA--A "KP"SGF*CVOL HKLI8"*HL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA T/
4.11.1. LA F0RN0LATI0N 0B}ET ....................................................................................................................................... SS
4.11.2. LA B00CLE B0-WBILE ............................................................................................................................................ S4
4.11.S. LA NETB0BE uCB .................................................................................................................................................... S4
RA-9A HKPICFLN *+NCFI8C*G+N HKP,,L8CPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TT
RA-/A "K*+NCFI8C*G+ Nb*C8V HL CFP*CLOL+C 0PF 8PN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TT
RA-RA I+L 6GI8"L ,GF 0PFC*8I"*\FL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TU
RA-TA 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TU
TA 8"PNNLN LC G6(LCN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TW
TA-A H*8VGCGO*L 8"PNNL:G6(LCN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TW
TA9A YPF*P6"LN HL 8"PNNL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TX
S.2.1. INPLENENTER BES C0NSTANTES PAR BES vARIABLES BE CLASSES ................................................................. S9
S.2.2. INPLENENTER 0NE NEN0IRE uL0BALE AvEC BES vARIABLES BE CLASSES ................................................... 6u
S.2.S. INITIALISATI0N BES vARIABLES BE CLASSES ........................................................................................................ 61
lll
TA/A FLCGIF NIF "L OGC 8"M ,*+P" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA U-
TARA FLCGIF NIF "LN OMCVGHLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA U9
TATA "LN OMCVGHLN HL 8"PNNL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA U/
TAUA "L C]0L HL "P FM0G+NL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA UR
TAWA L[M8IC*G+ HKI+L OMCVGHL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA UT
TAXA +GON HLN OMCVGHLN^ HLN PCCF*6ICN LC HLN YPF*P6"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA UT
TAZA 0PFPO\CFLN HLN OMCVGHLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA UT
TA-.A P00L" 0PF YP"LIF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA UU
TA--A NIF8VPFSL HL OMCVGHLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA UX
TA-9A NIF8VPFSL HL 8G+NCFI8CLIFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA UZ
TA-/A "L "P+8LOL+C HKI+ 0FGSFPOOL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA W.
TA-RA "LN 0P8aPSLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA W-
UA *+CLF,P8LN HL 0FGSFPOOPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA W/
UA-A "P +GC*G+ HK*+CLF,P8L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA W/
UA9A HM8"PFPC*G+ HK*+CLF,P8L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA W/
UA/A *O0"MOL+CLF I+L *+CLF,P8L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA W/
UARA "K*+CLF,P8L^ GIC*" HL 8G+8L0C*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA WR
6.4.1. EXENPLE : L'INTERFACE BINARYTREEINTERFACE ............................................................................................. 74
6.4.2. EXENPLE : 0NE INPLENENTATI0N BE L'INTERFACE BINARYTREEINTERFACE ............................................ 7S
UATA "K*+CLF,P8L^ GIC*" 8G+CFP8CIL" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA WU
6.S.1. EXENPLE : L'INTERFACE Q0E0E ............................................................................................................................. 76
6.S.2. EXENPLE : 0NE INPLENENTATI0N BE L'INTERFACE Q0E0E ............................................................................ 77
UAUA "K*+CLF,P8L^ GIC*" HKL+8P0NI"PC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA WZ
UAWA "K*+CLF,P8L^ I+L YIL 0PFC*8I"*\FL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA WZ
UAXA "K*+CLF,P8L^ HLN 0FG0F*MCMN L+ 8GOOI+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA X.
UAZA "L 0G*+C NIF "LN *+CLF,P8LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA X-
WA VMF*CPSL HL 8"PNNLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA X/
WA-A "P FL"PC*G+ HKVMF*CPSL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA X/
WA9A L+F*8V*NNLOL+C YNA FLHM,*+*C*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA X/
7.2.1. EXENPLE BE REBEFINITI0N .................................................................................................................................... 84
7.2.2. EXENPLE B'ENRICBISSENENT ................................................................................................................................. 8S
WA/A "KPF6FL HKVMF*CPSL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA XT
WARA P88\N J "P 8"PNNL O\FL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA XU
WATA VMF*CPSL LC 8G+NCFI8CLIFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA XW
WAUA "L 0G"]OGF0V*NOL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA XX
WAWA "*P*NG+ H]+PO*QIL HL OMCVGHL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Z.
WAXA "L OGC 8"M ,*+P" NIF I+L OMCVGHL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Z9
WAZA "L OGC 8"M ,*+P" NIF I+L 8"PNNL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Z/
WA-.A "L OGC 8"M ,*+P" NIF I+L YPF*P6"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Z/
WA--A VMF*CPSL N*O0"L LC OI"C*0"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Z/
WA-9A "P N*S+*,*8PC*G+ HL "KVMF*CPSL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ZR
WA-/A "KL[LO0"L HLN PFC*8"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ZR
WA-RA "LN 8"PNNLN P6NCFP*CLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ZW
WA-TA "LN OMCVGHLN P6NCFP*CLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ZX
WA-UA I+L +GIYL""L OGHM"*NPC*G+ HLN PFC8*"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -..
WA-WA FLYL+G+N NIF "LN *+CLF,P8LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -./
WA-XA OGHM"*NPC*G+ HLN PFC*8"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -.U
WA-ZA *+CLF,P8LN YNA 8"PNNLN P6NCFP*CLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -.U
WA9.A 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -.W
lv
XA L[8L0C*G+N LC LFFLIFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -.Z
XA-A "LN LFFLIFN J "KL[M8IC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -.Z
XA9A "L OLNNPSL HKLFFLIF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --.
XA/A P+P"]NLF "LN LFFLIFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --.
XARA "LN H*,,MFL+CN C]0LN HKLFFLIF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --.
XATA "L CFP*CLOL+C HLN LFFLIFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ---
XAUA L[LO0"L HL CFP*CLOL+CN c-d AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --9
XAWA L[LO0"L HL CFP*CLOL+CN c9d AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --/
XAXA L[LO0"L HL CFP*CLOL+CN c/d AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --/
XAZA "P 8"PINL ,*+P""] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --R
XA-.A FL0MFLF "LN LFFLIFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --R
XA--A 0FGSFPOOLF "L HM8"L+8VLOL+C HKI+L LFFLIF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --R
XA-9A HM,*+*F NLN 0FG0FLN L[8L0C*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --T
XA-/A PFFeCLF NLN 0FG0FLN L[8L0C*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --U
XA-RA 0FGSFPOOLF PYL8 HLN L[8L0C*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --W
XA-TA 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --X
ZA L+CFMLN:NGFC*LN c*fGd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --Z
ZA-A CGIC LNC G8CLC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --Z
ZA9A (PYP *fG AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --Z
ZA/A "LN ,"I[ HL NGFC*L HKG8CLCN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --Z
ZARA "LN ,"I[ HKL+CFML HKG8CLCN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -9.
ZATA "*FL "L 8G+CL+I HKI+ ,*8V*LF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -9.
ZAUA *fG 6I,,LF*NPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -99
9.6.1. B0FFERISATI0N EN ENTREE ................................................................................................................................. 122
9.6.2. B0FFERISATI0N EN S0RTIE ................................................................................................................................... 122
9.6.S. ATTENTI0N .............................................................................................................................................................. 12S
ZAWA H*,,MFL+CN C]0LN HL ,"I[ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -9/
ZAXA "LN ,"I[ HL 8PFP8C\FLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -9/
9.8.1. ECRIRE BANS 0N FL0X BE CARACTERES ............................................................................................................. 124
9.8.2. LIRE BANS 0N FL0X BE CARACTERES .................................................................................................................. 12S
9.8.S. A PR0P0S BES FL0X BE CARACTERES .................................................................................................................. 126
ZAZA ,"I[ HL HG++MLN 6*+P*FLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -9U
9.9.1. ECRIRE BES B0NNEES BINAIRES .......................................................................................................................... 127
9.9.2. LIRE BES B0NNEES BINAIRES ............................................................................................................................... 127
ZA-.A ,"I[ HKG6(LCN NMF*P"*NMN cVGFN 0FGSFPOOLd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -9X
9.1u.1. 0NE CLASSE SERIALISABLE ................................................................................................................................. 129
9.1u.2. ECRIT0RE B'0N 0B}ET SERIALISE ...................................................................................................................... 129
9.1u.S. LECT0RE B'0N 0B}ET SERIALISE ....................................................................................................................... 1Su
9.1u.4. PR0BLENES AvEC LES FL0X B'0B}ETS SERIALISES ........................................................................................ 1S1
ZA--A HKPICFLN ,"I[g AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/9
-.A 8GO0"MOL+CN *+H*N0L+NP6"LN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -//
-.A-A "L CFP+NC]0PSL c8PNCd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -//
-.A9A "K*+NCFI8C*G+ 6FLPa AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/R
-.A/A 8"PNNLN *O6F*QIMLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/T
-.ARA 8"PNNLN P+G+]OLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/T
-.ATA "LN 8G""L8C*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -/U
1u.S.1. ITERATI0N S0R LES C0LLECTI0NS .................................................................................................................... 1S6
1u.S.2. LES INTERFACES ................................................................................................................................................... 1S6
1u.S.S. LES CLASSES INPLENENTANT LES INTERFACES ............................................................................................. 1S8
1u.S.4. Q0ANB 0TILISER LES TABLES . ......................................................................................................................... 1S8
1u.S.S. Q0ANB 0TILISER LES LISTES . ........................................................................................................................... 1S8
v
1u.S.6. CB0ISIR SA STR0CT0RE BE B0NNEES .............................................................................................................. 1S8
1u.S.7. LES ALu0RITBNES ............................................................................................................................................... 1S9
--A 8G+NCFI*FL NG+ *VO cVGFN 0FGSFPOOLd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -R-
--A-A 0FGSFPOOLF I+L *VO AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -R-
--A9A "P 8G+NCFI8C*G+ HL "K*+CLF,P8L^ "LN 0P++LPI[ LC "LN "P]GICN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -R9
--A/A 8G+NCFI*FL I+L ,L+eCFL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -R9
--ARA QI* HG*C 8G++P_CFL QI* h AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -R/
--ATA I+L 6PFFL HL OL+I AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RR
--AUA I+ *CLO HL OL+I AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RR
--AWA "L OL+I AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RT
--AXA "P 6PFFL HL OL+I AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RU
--AZA 8FMLF "P 6PFFL HL OL+I AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RU
--A-.A "L 0FGSFPOOL QI* 8FML "P ,L+eCFL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RW
--A--A "L 8G+CL+I HL "P ,L+eCFL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RX
--A-9A "LN 8GO0GNP+CN Nb*+S AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RX
--A-/A I+L 0LC*CL P00"*8PC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RZ
--A-RA QIL" PFFP+SLOL+C h AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -RZ
--A-TA 8G"GF *+H*8PCGF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -T.
--A-UA 8G"GF 8VGGNLF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -T.
--A-WA LFPNL NLSOL+C AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -T.
--A-XA 6ICCG+N 0P+L" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -T-
--A-ZA HFPb*+S 0P+L" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -T9
--A9.A b*+HGb 0P+L" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -T9
--A9-A "P ,L+eCFL 0F*+8*0P"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TR
--A99A "LN "P]GICN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TR
--A9/A 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TT
-9A HLNN*+LF PYL8 NG+ *VO cVGFN 0FGSFPOOLd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TW
-9A-A "LN 8GGFHG++MLN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TW
-9A9A OY8 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TX
-9A/A "L HLNN*+ HP+N "LN (0P+L" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TX
-9ARA "L OGH\"L HL +GCFL P00"*8PC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TZ
12.4.1. LA CLASSE SEuNENT ........................................................................................................................................... 1S9
12.4.2. LE N0BELE ............................................................................................................................................................ 16u
12.4.S. 00 NETTRE LE N0BELE . ................................................................................................................................... 16u
-9ATA I+ L[LO0"L HL HLNN*+ HP+N I+ (0P+L" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -U-
-9AUA SFP0V*8N9H AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -U9
-9AWA I+ L[LO0"L HL HLNN*+ 0"IN NG0V*NC*QIM AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -U/
-9AXA 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -UT
-/A OY8 i OGH\"L^ YIL^ 8G+CFj"LIF cVGFN 0FGSFPOOLd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -UW
-/A-A "LN 0PCFG+N HL 8G+8L0C*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -UW
-/A9A FLCGIF NIF OY8 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -UW
-/A/A G6NLFYLF:G6NLFYP6"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -UX
1S.S.1. L'INTERFACE 0BSERvER ..................................................................................................................................... 168
1S.S.2. LA CLASSE 0BSERvABLE ..................................................................................................................................... 168
-/ARA "KG6NLFYP6"L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -UZ
-/ATA "KG6NLFYLF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -W.
-/AUA 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -W-
vl
-RA 0FGSFPOOLF NG+ *VO cVGFN 0FGSFPOOLd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -W/
-RA-A "LN MYM+LOL+CN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -W/
-RA9A "LN CFG*N 0FG8LNNIN "MSLFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -W/
-RA/A OGH*,*8PC*G+ HL "K*+CLF,P8L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -WR
-RARA FLCGIF NIF "L OGH\"L OY8 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -WR
-RATA P,,*+LF "LN FL"PC*G+N cVGFN 0FGSFPOOLd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -WU
-RAUA "*NCL+LF 0GIF I+ (6ICCG+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -WW
14.6.1. LE B00T0N ERASE SEuNENT ............................................................................................................................ 177
14.6.2. LE B00T0N C0L0R CB00SER ............................................................................................................................ 178
-RAWA "*NCL+LF 0GIF I+ OL+I *CLO AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -WZ
-RAXA "*NCL+LF 0GIF "P NGIF*N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -X.
14.8.1. 0N EXERCICE ......................................................................................................................................................... 182
14.8.2. BESSINER 0N SEuNENT ...................................................................................................................................... 18S
14.8.S. PR0uRANN0NS LA SELECTI0N .......................................................................................................................... 18S
-RAZA "LN PICFLN "*NCL+LFN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XT
-RA-.A 8G+8"IN*G+N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XU
-RA--A *+ ,*+L AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XU
-TA L"MOL+CN HL 0FGSFPOOPC*G+ GAGA cVGFN 0FGSFPOOLd AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XW
-TA-A "L 0F*+8*0L HKL+8P0NI"PC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XW
-TA9A "L 0F*+8*0L HL +G+:*+CFIN*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XW
-TA/A "L 0F*+8*0L HL HM"MSPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XX
-TARA "LN *+CLF,P8LN HL 0FGSFPOOPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XX
-TATA "KL+Y*FG++LOL+C HKI+ G6(LC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XZ
-TAUA *VO LC L+Y*FG++LOL+CN HLN G6(LCN SFP0V*QILN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XZ
-TAWA 8PCMSGF*NLF "LN G6(LCN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -XZ
-TAXA "KVMF*CPSL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -Z.
-TAZA VMF*CPSL YNA 8GO0GN*C*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -Z.
-TA-.A "KLFFLIF k AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -Z-
-TA-A "L NGIN:8"PNNLOL+C AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -Z-
-TA9A +GCFL L[LO0"L i "LN L[0FLNN*G+N PF*CVOMC*QILN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -Z/
1S.2.1. LES EXPRESSI0NS ................................................................................................................................................. 19S
1S.2.2. N0TES S0R LE PR0CESS0S BE BEvEL0PPENENT ........................................................................................... 194
1S.2.S. 0NE NA0vAISE INPLENENTATI0N BES EXPRESSI0NS .................................................................................. 194
1S.2.4. LA B0NNE S0L0TI0N ........................................................................................................................................... 197
1S.2.S. ETENBRE AvEC 0N N00vEL 0PERATE0R BINAIRE ......................................................................................... 2u1
1S.2.6. ETENBRE AvEC BES EXPRESSI0NS F0NCTI0NNELLES ................................................................................... 2u2
-TA/A 0GIF I+L 6G++L OGHM"*NPC*G+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9./
-TARA "K*+CLF,P8L GI "P 8"PNNL P6NCFP*CL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9./
-TATA "KL[CL+N*G+ OGHI"P*FL AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9.R
-TAUA P00FG8VL 0FG(LC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9.U
-TAWA HLF+*LF 8G+NL*"N AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 9.W
1
1. Introduct|on |'or|ent ob[et
1.1. Les ob[ect|fs des cours d'Informat|que
L'ob[ecLlf de la 8Cl lnformaLlque esL de :
vous donner de bonnes praLlques de programmaLlon eL les savolr-falre permeLLanL de
Lravalller dans un conLexLe de developpemenL loglclel professlonnel.
vous donner une bonne maiLrlse de la programmaLlon orlenLee ob[eL au Lravers du langage
!ava d'usage repandu dans l'lndusLrle alnsl que du langage C, blen adapLe a la
programmaLlon sysLeme.
vous donner les bases necessalres pour forger un modele du foncLlonnemenL d'un
ordlnaLeur eL des grandes foncLlons du sysLeme d'explolLaLlon qul l'opere.
vous donner des bases solldes en algorlLhmlque eL sLrucLures de donnees eL lnLrodulre la
complexlLe algorlLhmlque.
vous donner une vlslon des fondemenLs Lheorlques de l'lnformaLlque.
1.2. La ca|cu|ab|||t
Les maLhemaLlclens, blen avanL l'lnvenLlon des ordlnaLeurs, se sonL longLemps pose le probleme de
la calculablllLe. Cn peuL LenLer de deflnlr la ca|cu|ab|||t en dlsanL qu'une valeur esL calculable s'll
exlsLe un procede auLomaLlsable, un a|gor|thme, permeLLanL de calculer ceLLe valeur. Cn connaiL des
foncLlons calculables : eLanL donne un enLler o > 0, calculer la o
leme
declmale du nombre ! esL
calculable. PlsLorlquemenL, la premlere foncLlon non calculable esL due a Alan 1urlng. our la deflnlr,
on numeroLe Lous les programmes d'un langage de programmaLlon a parLlr de 0 dans l'ordre
lexlcographlque. La fonct|on d'arrt prend en argumenL un enLler naLurel o, elle consldere le
programme l donL le numero esL o eL rend 1 sl l'execuLlon de ce programme se Lermlne, 0 slnon. Cn
peuL demonLrer Lres slmplemenL qu'll n'exlsLe pas d'algorlLhme qul permeL de calculer ceLLe foncLlon.
Cue slgnlfle Lre calculable ? ue nombreux maLhemaLlclens onL LenLe de donner une deflnlLlon de la
calculablllLe : les Machlnes de 1urlng (A. 1urlng), les loncLlons arLlelles 8ecurslves (l8, A. Church,
S. C. kleene), le !-calcul (A. Church), la Loglque ComblnaLolre (P. 8. Curry), l'u8M (ordlnaLeur
ldeallse), eLc. 1ouLes ces deflnlLlons, aussl dlfferenLes qu'elles solenL, flnalemenL se recoupenL. Ce qul
esL calculable selon l'une de ces deflnlLlons l'esL aussl selon les auLres. u'ou la Lhese de Church
(1930) qul enonce que la noLlon de calculablllLe esL unlque.
2
1.3. L'ord|nateur
C'esL le maLhemaLlclen !ohn von neumann qul, en 1940, a lnvenLe l'ordlnaLeur acLuel aussl appele
Mach|ne de Von Neumann. u'auLres Lypes d'ordlnaLeurs onL eLe conus eL consLrulLs mals lls resLenL
conflnes a des appllcaLlons speclflques. Lxemples : archlLecLures vecLorlelles (SlMu, 5loqle losttoctloo
Moltlple uoto), archlLecLures plpe-llne (MlMu, Moltlple losttoctloo oo Moltlple uoto), archlLecLures a
floLs de donnees (uotoflow otcbltectotes), eLc.
La Machlne de von neumann ressemble a cecl :
Cn y dlsLlngue :
un bus qul esL en charge des communlcaLlons enLre Lous les auLres elemenLs.
une memolre lenLe mals permanenLe qul peuL conLenlr des donnees qul survlvronL a
l'exLlncLlon de l'ordlnaLeur. C'esL en general des d|sques durs qul assurenL ceLLe foncLlon.
une mmo|re kAM (kooJom Access Memoty), memolre raplde mals non permanenLe,
conLenanL des donnees a acces Lres raplde mals qul ne survlvronL pas a l'exLlncLlon de
l'ordlnaLeur. C'esL ce que l'on appelle la memolre vlve de l'ordlnaLeur.
ues canaux d'entre-sort|e qul permeLLenL d'acceder aux elemenLs exLerleurs a
l'ordlnaLeur : l'ecran, le clavler, le reseau lnLerneL, le reseau Wlfl, eLc.
un processeur conLenanL des reg|stres eL une un|t ar|thmt|que et |og|que (uAL) :
" Les reglsLres sonL de peLlLes memolres a acces Lres rapldes eL en nombre llmlLe. Ces
reglsLres onL une Lallle appelee mot.
" Le processeur esL le cerveau (depourvu d'lnLelllgence) de l'ordlnaLeur. Les
lnsLrucLlons que l'uAL salL execuLer sonL represenLees sous forme d'ocLeLs dans la
memolre 8AM. ll ne salL execuLer que des lnsLrucLlons comme :
! lalre des operaLlons arlLhmeLlques enLre deux reglsLres.
! lalre des operaLlons loglques blL a blL enLre deux reglsLres.
! 1ransferer un moL depuls un reglsLre vers la memolre raplde (8AM).
! 1ransferer un moL depuls la memolre raplde (8AM) vers un reglsLre.
! SauL : conLlnuer l'execuLlon a un auLre endrolL de la memolre.
! SauL condlLlonnel : effecLuer un sauL sl une condlLlon esL verlfle.
! LLc.
3
Les operaLlons que l'uAL salL execuLer sonL dependanLes du processeur. Llles peuvenL Lre plus ou
molns sophlsLlquees. 8len enLendu, ceLLe descrlpLlon esL slmpllflee mals elle esL sufflsanLe pour le
cours de !ava.
1.4. Les programmes
Ln 1976, nlklhaus WlrLh, le pere du langage ascal, ecrlL un llvre fondamenLal lnLrodulsanL la
programmaLlon sLrucLuree nee avec le langage Algol :
A|gor|thms + Data Structures = rograms
1
ClasslquemenL, on presenLe l'execuLlon d'un programme comme eLanL des sLrucLures de donnees
qul sonL LralLees par un algorlLhme appeles le programme. Le programme eL les donnees sonL
sLockes dans la memolre 8AM pour pouvolr commencer l'execuLlon.
1.4.1. La mmo|re kAM
La memolre 8AM
2
esL composee d'une sulLe d'ocLeLs numeroLes a parLlr de zero. un octet esL
compose de 8 blLs d'lnformaLlon 0 ou 1. L'ocLeL esL la plus peLlLe parLle adressab|e de la memolre :
lorsque l'on veuL llre des donnees dans la memolre ou lorsque l'on veuL ecrlre des donnees dans la
memolre, on le falL Lou[ours ocLeLs par ocLeLs ou groupes d'ocLeLs par groupes d'ocLeLs. La memolre
esL loglquemenL decoupee en mots consecuLlfs. un moL esL forme de 4 ocLeLs sur une machlne
32 blLs eL de 8 ocLeLs sur une machlne 64 blLs. L'adresse d'une donnee en memolre esL le numero du
premler ocLeL de ceLLe donnee.
1.4.2. Les donnes d'un programme
Les donnees d'un programme sonL represenLees en memolre par des sulLes d'ocLeLs. Lxemples :
une valeur numerlque enLre 0 eL 233 peuL Lre represenLee par un seul ocLeL qul code la
valeur en base 2 en uLlllsanL les 8 blLs (0 ou 1).
un nombre plus grand sera represenLe par plusleurs ocLeLs qul conLlendronL sa
represenLaLlon en base 2. Cn uLlllsera un moL ou un deml-moL.
ll y a molns de 236 caracLeres (poncLuaLlon comprlse) dans la langue franalse usuelle. Cn
peuL donc declder d'aLLrlbuer un numero enLre 0 eL 233 a chaque caracLere eL represenLer
celul-cl par un ocLeL.
Lorsqu'll uLlllse un langage de programmaLlon Lel que !ava, le programmeur a raremenL besoln de
savolr commenL les donnees sonL represenLees en memolre. un langage de programmaLlon Lel que
!ava esL appele un langage de hauL nlveau.
1.4.3. La base des programmes
Chaque operaLlon que l'uAL salL execuLer possede un codage sous la forme d'une sulLe d'ocLeLs. Les
programmes sonL des sulLes d'lnsLrucLlons pour l'uAL qul sonL codes par des sulLes d'ocLeLs. L'uAL
salL llre ces ocLeLs en memolre eL salL effecLuer les operaLlons decrlLes sous forme d'ocLeLs.
L'ordlnaLeur repeLe en boucle le Lravall sulvanL :
Llre l'lnsLrucLlon sulvanLe en memolre.
La decoder.
LxecuLer l'operaLlon decrlLe.
1
AlgorlLhmes + SLrucLures de donnees = rogrammes
2
uorenavanL, quand nous dlrons la memolre , ce sera la memolre 8AM .
4
1.4.4. L'|nvent|on des |angages de programmat|on
Ln 1938, !ohn 8ackus (l8M) lnvenLe le premler |angage de programmat|on nomme lC818An. Sur les
premlers ordlnaLeurs (1940-1960), on ecrlvalL dlrecLemenL les ocLeLs pour programmer. un langage
de programmaLlon permeL de decrlre les algorlLhmes de manlere llslble. un programme, appele le
comp||ateur, permeL de Lransformer l'algorlLhme decrlL dans le langage de programmaLlon en une
sulLe d'ocLeLs que l'uAL salL execuLer.
1.4.S. Les parad|gmes de programmat|on
un langage de programmaLlon permeL au programmeur d'ecrlre son programme de manlere llslble
avec des concepLs de hauL nlveau, c'esL-a-dlre des concepLs qul n'apparalssenL pas dans l'ordlnaLeur
nu. Alnsl, Lous les langages proposenL la noLlon de Lables de donnees numerlques slmllalres aux
Lables que l'on peuL redlger sol-mme sur une feullle. un auLre programme, appele le comp||ateur,
LradulL ces concepLs de hauL nlveau en lnsLrucLlons pour le mlcro-processeur de l'ordlnaLeur. Ces
lnsLrucLlons seronL ensulLe chargees en memolre pour Lre execuLes.
ll exlsLe dlfferenLs paradlgmes de programmaLlon, c'esL-a-dlre dlfferenLs sLyles de langages :
Le paradlgme |mprat|f esL celul des langages de programmaLlon ou les programmes sonL
des |nstruct|ons encadrees par des structures de contr|e de l'execuLlon. Cn parle de
langage de programmaLlon lmperaLlf ou procdura|.
Le paradlgme fonct|onne| esL celul des langages qul permeLLenL de deflnlr des foncLlons au
sens usuel du Lerme. Cn demande alors a l'ordlnaLeur de calculer une expresslon.
Le paradlgme |og|que esL celul des langages ou l'on decrlL le probleme par des formules
loglques eL ou l'on demande a l'ordlnaLeur de demonLrer un Lheoreme.
Le paradlgme or|ent ob[et esL celul des langages ou l'on modellse un probleme par une
collecLlon d'ob[eLs qul communlquenL enLre eux par envols de messages.
1.4.6. La programmat|on |mprat|ve
Ln programmaLlon lmperaLlve, on a des structures de donnes comme, par exemple, un Lableau de
nombres. uls on a des procdures qul prennenL en parameLres ces sLrucLures de donnees. Llles
effecLuenL des acLlons sur ces donnees eL/ou calculenL des resulLaLs a parLlr de ces donnees.
Lxemp|e : une procedure pour Lrler (reordonner) les elemenLs d'un Lableau en ordre crolssanL. Ce
Lype de programmaLlon esL le plus repandu. ll permeL de resoudre Lous les problemes pour lesquels
on peuL consLrulre une sulLe de commandes apporLanL une soluLlon.
ll exlsLe des cas ou le paradlgme ob[eL, qul eLend le paradlgme lmperaLlf, apporLe de la faclllLe dans
la programmaLlon eL une vlslon plus clalre du probleme a resoudre.
1.S. La programmat|on or|ent ob[et
Cn a couLume de dlre que la programmaLlon orlenLe ob[eL (C.C.) a eLe lnLrodulLe par le langage
Slmula a l'unlverslLe d'Cslo en Suede en 1967. Le probleme pose eLalL celul de la slmulaLlon d'un
ensemble de roboLs dans une enLreprlse. Lssayer de resoudre ce probleme a l'alde de la
programmaLlon lmperaLlve esL un vral casse-LLe LanL les lnLeracLlons enLre les dlfferenLs elemenLs
du problemes sonL nombreuses eL lmprevlslbles. 1enLer d'lmaglner un programme cenLrallse qul
plloLe les roboLs en modlflanL une sLrucLure de donnees represenLanL l'eLaL des roboLs eL de
l'envlronnemenL n'esL pas lmposslble mals Lres dlfflclle.
La soluLlon esL l'orlenLe ob[eL. Ln orlenLe ob[eL, on va decrlre chacun des elemenLs du probleme par
une c|asse. Cela concerne les roboLs mals aussl Lous les elemenLs du probleme, par exemple le posLe
de conLrle ou slege le conLrleur humaln.
La classe d'un ob[eL decrlL les donnees conLenues dans l'ob[eL. un roboL aura par exemple un nlveau
d'energle represenLe par un nombre comprls enLre 0 eL 100, une poslLlon composee de deux
3
coordonnees reelles, un vecLeur vlLesse, eLc. Ce sonL les attr|buts de l'ob[eL. !usqu'lcl, ce n'esL pas
Lres dlfferenL de la descrlpLlon d'une sLrucLure de donnees classlque. La dlfference, c'esL que les
ob[eLs peuvenL s'envoyer des messages. un ob[eL recevanL un message dolL repondre a ce message
apres avolr effecLue quelques calculs eL/ou quelques acLlons. Lxemples de messages :
L'humaln envole un message a un roboL pour lul dlre de demarrer ou d'arrLer son
foncLlonnemenL.
un roboL slgnale au conLrle que son nlveau d'energle esL Lrop bas.
ueux roboLs se heurLenL, les capLeurs envolenL des messages.
La classe decrlL egalemenL commenL les ob[eLs repondenL aux messages. Ce sonL les mthodes de
l'ob[eL. ar exemple, sl un ob[eL reolL le message start() du conLrleur, ll demarre eL renvole la
reponse done sl le demarrage s'esL blen passe ou la reponse failed sl le demarrage a echoue.
Le programmeur decrlL chacun des ob[eLs de l'uslne par une classe. Au lancemenL du programme, le
programmeur cree des ob[eLs. C'esL le processus d'|nstanc|at|on. ll creera un posLe de conLrle des
roboLs, un cerLaln nombre de roboLs, eLc. Les ob[eLs lnLeraglssenL par envol de messages. Les
messages lnlLlaux sonL envoyes par le conLrleur humaln. ll n'y a pas de programme cenLrallse qul
gere l'ensemble du programme.
1.6. Le cas des |nterfaces graph|ques
1ouL ce qul apparaiL sur l'ecran d'un ordlnaLeur falL parLle des lnLerfaces graphlques : fenLres,
menus, bouLons, champs d'enLree, zones de dessln, eLc. L'uLlllsaLeur de l'ordlnaLeur, par ses acLlons
avec le clavler eL la sourls, declenche des acLlons : creaLlon d'une nouvelle fenLre, acLlon assoclee a
un bouLon, eLc. CerLalns changemenLs sonL auLomaLlques : les anlmaLlons par exemple. Comme dans
le cas des roboLs, on pourralL lmaglner une sLrucLure de donnees decrlvanL l'eLaL de l'lnLerface
graphlque. LL ll seralL LouL aussl dlfflclle d'lmaglner un programme manlpulanL ceLLe sLrucLure qul esL
Lres dynamlque car des fenLres se creenL ou dlsparalssenL a LouL momenL, des ob[eLs sonL bouges
sur l'ecran, eLc. Cn pense mme qu'un Lel programme seralL de nos [ours LellemenL complexe a
lmaglner que personne ne pourralL l'ecrlre.
uans l'approche orlenLe ob[eL des lnLerfaces graphlques, chaque elemenL apparalssanL sur l'ecran esL
un ob[et au sens de Slmula, y comprls les elemenLs LemporalremenL lnvlslbles comme une fenLre
cachee par une auLre fenLre. Chacun de ses ob[eLs a des attr|buts : ses coordonnees sur l'ecran, ses
dlmenslons, sa profondeur (qul esL devanL qul ?), eLc. Chacun de ses ob[eLs a des mthodes qul lul
permeLLenL de repondre aux messages qu'll reolL. Les aLLrlbuLs eL les meLhodes d'un ob[eL
dependenL de son Lype (fenLre, bouLon, eLc.) qul esL decrlL par une c|asse qul conLlendra les
declaraLlons d'aLLrlbuLs eL de meLhodes.
Le prlnclpal emeLLeur de message esL l'uLlllsaLeur de l'ordlnaLeur :
un cllc de sourls avec l'un des bouLons de la sourls.
un deplacemenL de la sourls.
La frappe d'une Louche du clavler.
LLc.
Ln reponse a une acLlon de l'uLlllsaLeur sur l'un des ob[eLs de l'lnLerface, ceL ob[eL peuL emeLLre des
messages a desLlnaLlon d'auLres ob[eLs de l'lnLerface graphlque. voyons cela sur un exemple.
volcl l'lnLerface d'un loglclel qul permeL d'lnLerroger un annualre. Cn enLre les donnees sur la
personne recherchee dans la fenLre prlnclpale, on cllque ensulLe sur le bouLon Search eL une
fenLre esL creee avec le resulLaL de la recherche. un bouLon Clear permeL de relnlLlallser les
champs d'enLree. un bouLon Quit permeL de Lermlner l'appllcaLlon. Cela donne cecl :
6
nous voyons dlfferenLs ob[eLs dans ceL lnLerface graphlque : des fenLres, des bouLons, des champs
d'enLree, eLc. our qu'un ob[eL pulsse envoyer un message a un auLre ob[eL, ll fauL qu'll connalsse ceL
auLre ob[eL. un ob[eL connaiL un auLre ob[eL s'll possede une rfrence sur ceL auLre ob[eL. une
reference sur un ob[eL esL un aLLrlbuL qul ldenLlfle l'ob[eL reference. Le programmeur, lorsqu'll
conolL son appllcaLlon, deLermlne les llens enLre les ob[eLs : quel ob[eL connaiL quel auLre ob[eL ?
1.6.1. Arch|tecture des ob[ets
Lssayons d'lmaglner l'archlLecLure des ob[eLs, c'esL-a-dlre quel ob[eL possede une reference sur quel
auLre ob[eL dans noLre appllcaLlon :
La fenLre prlnclpale conLlenL Lrols champs d'enLree. Comme elle dolL y acceder, elle dolL
connaiLre ces champs d'enLree. La fenLre prlnclpale dolL donc avolr Lrols aLLrlbuLs qul sonL
des references sur les champs d'enLree.
La fenLre prlnclpale cree les fenLres resulLaLs. Lorsque l'appllcaLlon se Lermlnera, elle devra
falre dlsparaiLre ces fenLres. La fenLre prlnclpale dolL donc avolr un aLLrlbuL qul esL une
llsLe de references sur les fenLres resulLaLs.
une fenLre resulLaL peuL Lre fermee en cllquanL sur son bouLon Close. Mals ll ne fauL pas
oubller que la fenLre prlnclpale malnLlenL une llsLe de fenLres resulLaLs, volr cl-dessus. Sl
une fenLre resulLaL esL fermee, ll faudra qu'elle prevlenne la fenLre prlnclpale. uonc
chaque fenLre resulLaL dolL avolr un aLLrlbuL qul esL une reference sur la fenLre prlnclpale.
1ous les bouLons declenchenL des acLlons : bouLons Clear, Search eL Quit dans la
fenLre prlnclpale, bouLon Close dans les fenLres resulLaLs. Lorsque l'uLlllsaLeur cllquera
sur ces bouLons, le plus slmple esL que le bouLon demande a sa propre fenLre de falre le
Lravall. Chaque bouLon dolL avolr un aLLrlbuL qul esL une reference sur sa propre fenLre.
Cn peuL represenLer l'archlLecLure de l'lnLerface graphlque alnsl :
7
1.6.2. Cascade de messages
Cue se passe-L-ll quand l'uLlllsaLeur cllque sur le bouLon Clear ? ll fauL, blen sr, vlder les Lrols
champs d'enLree de la fenLre prlnclpale.
Lors que l'uLlllsaLeur cllque sur le bouLon Clear, le bouLon reolL un message click().
Le bouLon se conLenLe alors d'envoyer le message clearFields() a la fenLre qu'll
connaiL, volr l'archlLecLure des ob[eLs.
La fenLre envole alors le message clear() a chacun des champs d'enLree.
A la recepLlon du message clear(), chaque champ d'enLree efface le LexLe qu'll conLlenL. LL ll
renvole le message ok() a la fenLre.
Cuand la fenLre a reu les Lrols messages ok() de ses champs d'enLree, elle renvole le
message ok() au bouLon Clear.
1ouL cecl peuL se monLrer alnsl :
uls :
uls :
8
uls :
uls :
uls :
LL enfln :
9
1.6.3. Les mthodes
Le programmeur dolL programmer des meLhodes qul deLermlnenL les reponses aux messages reus
par les ob[eLs. Ces meLhodes son en general parLlculleremenL slmples. Alnsl la meLhode
correspondanL au message click() du bouLon Clear effecLuera :
1. Se desslner enfonce a l'ecran.
2. Lnvoyer le message clearFields() a la fenLre.
3. ALLendre la reponse ok().
4. Se desslner releve a l'ecran.
AuLre exemple, la meLhode qul correspond au message clearFields() reu par la fenLre
prlnclpale effecLuera :
1. Lnvoyer le message clear() au champs d'enLree First name.
2. ALLendre la reponse ok().
3. Lnvoyer le message clear() au champs d'enLree Middles names.
4. ALLendre la reponse ok().
3. Lnvoyer le message clear() au champs d'enLree Last name.
6. ALLendre la reponse ok().
7. 8envoyer la reponse ok().
Cn volL sur ces exemples que chacune des meLhodes esL Lres slmple.
Chaque ob[eL possede ses propres meLhodes pour repondre aux messages qu'll reolL. Les
algorlLhmes lmplemenLes de ceLLe manlere sonL morceles en parLles Lres slmples eL reparLles sur les
ob[eLs. Chaque ob[eL esL responsable des lnLeracLlons avec son envlronnemenL qul esL compose des
ob[eLs qu'll connaiL. Ln falL, les algorlLhmes de chaque ob[eL sonL plus faclles a concevolr eL plus
concls qu'un algorlLhme global qul LenLeralL de LouL gerer.
1.6.4. Deux pr|nc|pes
Sur l'exemple des lnLerfaces graphlques, on volL apparaiLre deux prlnclpes.
Le pr|nc|pe de non-|ntrus|on.
Cn evlLe de Lravalller sur un ob[eL depuls l'exLerleur de l'ob[eL.
Alnsl le bouLon Clear ne va pas lul-mme vlder les champs d'enLree dans la fenLre prlnclpale. ll
demande a la fenLre de le falre. lnLerL ? Sl l'on ra[ouLe un champ d'enLree dans la fenLre, ll ne
faudra reLoucher que le programme de la fenLre.
Le pr|nc|pe de d|gat|on.
Cuand un Lravall dolL Lre falL, demander sl posslble aux auLres ob[eLs de le falre.
lnLerL ? Cn encapsule eL on locallse le code dans un nombre resLrelnL de classes.
1.6.S. Le f|ot d'excut|on
Cn appelle f|ot d'excut|on d'un programme la sulLe des acLlons execuLees par le programme.
Comme nous l'apprendrons, ces acLlons peuvenL Lre :
des envols de messages ,
des calculs de valeurs ,
des enLrees - sorLles ,
10
llre ou ecrlre des donnees en memolre ,
eLc.
Ces acLlons sonL execuLees squent|e||ement. Alnsl dans la meLhode que nous avons donnee en
exemple :
1. Se desslner enfonce a l'ecran.
2. Lnvoyer le message clearFields() a la fenLre.
3. ALLendre la reponse ok().
4. Se desslner releve a l'ecran.
on aLLendra que l'acLlon 1 se Lermlne avanL de passer a l'acLlon 2, puls que l'acLlon 2 se Lermlne pour
passer a l'acLlon 3, puls que l'acLlon 3 se Lermlne avanL de passer a l'acLlon 4.
1.7. Conc|us|ons
Les ob[ets sonL des enLlLes lnformaLlques qul communlquenL par envols de messages. Les ob[eLs
conLlennenL des valeurs appelees attr|buts. arml les aLLrlbuLs, on peuL Lrouver des rfrences sur
d'auLres ob[eLs. une reference sur un ob[eL permeL de lul envoyer des messages. our chaque Lype
de message que l'ob[eL peuL recevolr, l'ob[eL connaiL une mthode assoclee au Lype de message.
CeLLe meLhode esL une procedure qul esL excute par |'ob[et lorsqu'll reolL le Lype de message
assocle. un Lype d'ob[eL esL decrlL par une c|asse. La classe decrlL les aLLrlbuLs, noms eL Lypes de
valeurs. La classe decrlL les meLhodes uLlllsees pour repondre aux messages.
Le programmeur peuL creer des ob[eLs a parLlr de la classe. C'esL le processus d'|nstanc|at|on. Cn dlL
que les ob[eLs sonL des lnsLances de la classe.
1.8. A propos de Iava
lls exlsLenL Lrols grandes ecoles d'orlenLe ob[eL : l'ecole Small1alk-!ava, l'ecole C++-Ada eL l'ecole
Llffel. !ava a eLe cree en 1991 par Sun MlcrosysLems. L'ob[ecLlf eLalL la programmaLlon de peLlLs
apparells comme des Lelecommandes. !ava fuL ensulLe appllque a la programmaLlon d'appllcaLlons
dans les navlgaLeurs Web : les app|ets. ll porLe son nom a cause de la bolsson preferee de ses
concepLeurs. uepuls, Sun MlcrosysLems a eLe racheLe par Cracle.
!ava esL malnLenanL un langage de programmaLlon generallsLe uLlllse par l'lndusLrle dans une
mulLlLude de domalne. !ava propose un Lres grand nombre de blblloLheques qul formenL une bo|te
out||s pour le developpemenL de loglclels. ues communauLes de developpeurs proposenL sur
lnLerneL des soluLlons (ensemble de classes) plus ou molns elaborees, generlques, eprouvees eL
documenLees, permeLLanL le developpemenL d'appllcaLlons en general a grande echelle. C'esL une
des grandes forces de !ava.
une caracLerlsLlque lmporLanLe de !ava esL la portab|||t, c'esL-a-dlre qu'une mme appllcaLlon
ecrlLe en !ava peuL s'execuLer sur dlfferenLs ordlnaLeurs en s'absLrayanL des speclflclLes du maLerlels
eL du sysLeme. our un langage plus classlque, le comp||ateur produlL a parLlr du programme un
flchler d'ocLeLs, le flchler execuLable, qul esL un programme execuLable par l'uAL. Ce flchler
execuLable esL dependanL du processeur eL du sysLeme d'explolLaLlon. !ava esL un langage porLable
car ll esL mls en ouvre par une mach|ne v|rtue||e. our assurer la porLablllLe en !ava, sur chaque
ordlnaLeur, un lnLermedlalre meL en ouvre une machlne vlrLuelle emulanL un envlronnemenL
d'execuLlon qul esL Lou[ours le mme sur Lous les ordlnaLeurs. La machlne vlrLuelle de !ava s'appelle
la !vM : !ava vlrLual Machlne.
11
1.9. A propos du cours
Le cours de !ava (lnl 103) n'esL pas un cours d'algorlLhmlque. L'algorlLhmlque esL eLudle en
SuA (lnl 101). nous falsons parfols reference au cours SuA dans lnl 103.
La programmaLlon orlenLee ob[eL esL speclflque. ll ne fauL pas chercher a reprodulre ce que l'on
a pu apprendre avec d'auLres langages.
Le cours en llgne eL les 1s sonL en hLLp://www.lnfres.ensL.fr/~belloL/Cours!ava. C'esL la que
vous devrez le consulLer.
Le cours ne conLlenL pas 1Cu1 sur !ava. Ln revanche, Goog|e (ou un auLre) esL un excellenL aml
qul vous permeL de LouL Lrouver. ll fauL vous y hablLuer sl ce n'esL de[a falL.
n'oubllez pas que les pro[eLs AC1 onL forLemenL besoln du langage !ava.
uans l'enselgnemenL superleur comme dans les enLreprlses, l'usage de LransparenLs pro[eLes sur
ecran esL la norme. ll fauL vous y hablLuer.
L'anglals esL la langue de l'lnformaLlque, c'esL comme a. uLlllser des leLLres auLres que celles de
l'alphabeL anglals (leLLres accenLuees par exemple) rlsque de vous exposer a de gros problemes.
un bon consell : uLlllser l'anglals ou le franglals ou le globlsh pour nommer vos programmes,
ecrlre vos commenLalres, eLc.
13
2. 8ases de |a programmat|on
2.1. Une c|asse
Supposons que l'on ecrlve un programme LralLanL de concepLs geomeLrlques dans un plan. La c|asse
Point dolL decrlre un polnL du plan :
public class Point
{
private int x ;
private int y ;
}
Cn volL l'en-LLe de la c|asse Point qul commence par public class puls le nom de la classe,
puls une accolade ouvranLe a laquelle correspondra une accolade fermanLe. un polnL esL caracLerlse
par ses deux coordonnees dans le plan. Ce sonL deux attr|buts eL lls sonL nommes x eL y. AvanL les
noms des aLLrlbuLs, on Lrouve private int. Le mot c| private dolL Lou[ours preceder les
declaraLlons d'aLLrlbuLs, nous y revlendrons plus Lard. Cuand au type int, cela slgnlfle que les
aLLrlbuLs x eL y peuvenL prendre des valeurs enLleres, nulles, poslLlves ou negaLlves.
2.2. Une var|ab|e
Sl une classe esL deflnle, la classe Point dans noLre exemple, ll esL posslble de creer un ob[eL de
ceLLe classe. our cela, ll fauL une var|ab|e pouvanL conLenlr une rfrence sur un ob[et de |a c|asse
Point. Celle-cl se declare alnsl :
Point p ;
une Lelle varlable pourra conLenlr la valeur null ou blen une reference sur un ob[eL de la classe
Point. Sl elle conLlenL la valeur null, cela veuL dlre qu'elle ne reference aucun polnL.
une varlable esL une zooe Je mmolte oomme. lcl, le nom esL p. Llle peuL conLenlr des
valeurs d'un cerLaln type. lcl, ce sonL des tfteoces sot Jes objets Je lo closse Point.
14
Lorsque l'on ecrlL :
Point p ;
Le langage !ava uLlllse une zone consLlLuee d'un cerLaln nombre d'ocLeLs de la memolre 8AM eL
celle-cl esL nommee p. Le programmeur n'a pas besoln de savolr ou esL ceLLe zone memolre nl
commenL les donnees sonL codees avec des ocLeLs.
Cn peuL slmplemenL represenLer la varlable alnsl :
2.3. Crat|on d'un ob[et
La varlable p esL une varlable de Lype reference sur un Point. Cn peuL alors creer un ob[eL de la
classe Point avec l'lnsLrucLlon new :
p = new Point() ;
Le symbole = esL appele symbo|e d'affectat|on. La varlable a gauche du symbole reolL la valeur
a drolLe du symbole. lcl, la valeur esL une reference sur un ob[eL de la classe Point qul esL cree par
l'lnsLrucLlon new.
une erreur commune chez les debuLanLs esL de confondre le symbole d'affecLaLlon
= des langages de programmaLlon avec le symbole d'egallLe des maLhemaLlques.
uans les langages de programmaLlon, le symbole d'egallLe s'ecrlL == .
Cn peuL regrouper la declaraLlon de la varlable eL la creaLlon de l'ob[eL en une seule lnsLrucLlon :
Point p = new Point() ;
uans les deux cas, le resulLaL esL le mme :
La reference esL represenLee par une fleche vers l'ob[eL reference. Cn noLera que p ne conLlenL pas
le polnL mals une reference sur le polnL .
2.4. In|t|a||sat|on des ob[ets
une quesLlon se pose : quelles sonL les valeurs des aLLrlbuLs x eL y apres la creaLlon de l'ob[eL ? La
speclflcaLlon de !ava nous apprend que des aLLrlbuLs de Lype int sonL Lou[ours lnlLlallse avec la
valeur 0 (zero). Cn a donc :
13
ALLenLlon ! L'lnlLlallsaLlon des aLLrlbuLs de Lype int avec la valeur 0 esL vrale en !ava
mals elle n'esL pas vrale dans Lous les langages de programmaLlon.
2.S. Aff|cher |es attr|buts
CommenL afflcher les cordonnees d'un ob[eL de la classe Point ? Cn peuL blen sr demander a
l'ob[eL de la classe Point ses coordonnees x eL y, puls les afflcher. CependanL, une regle en orlenLe
ob[eL esL d'evlLer d'aglr depuls l'exLerleur de l'ob[eL (rg|e de non |ntrus|on, cf. 1.6.4). Alnsl, on
evlLera, sl ce n'esL pas Lrop compllque a reallser, les operaLlons de lecLure eL d'ecrlLure des aLLrlbuLs.
Cn va donc demander a l'ob[eL de Lype Point d'afflcher ses coordonnees. C'esL aussl
une appllcaLlon du pr|nc|pe de d|gat|on, cf. 1.6.4.
our cela, nous allons lul envoyer un message writeCoordinates(). Cela donne :
Point p = new Point() ;
p.writeCoordinates() ;
Cn envole un message a un ob[eL slmplemenL en meLLanL la reference a l'ob[eL sulvle d'un polnL sulvl
du message. ll fauL alors decrlre quelle esL la meLhode qul repondra a ce message. CeLLe declaraLlon
se falL dans la classe de l'ob[eL lcl en gras :
public class Point
{
private int x ;
private int y ;
public void writeCoordinates()
{
System.out.print(x = ) ;
System.out.println(x) ;
System.out.print(y = ) ;
System.out.println(y) ;
}
}
Cn volL que la meLhode permeLLanL de repondre au message writeCoordinates() porLe
exacLemenL son nom. Llle esL slmplemenL declaree dans la classe. Les auLres elemenLs de langages
sonL les sulvanLs :
Le moL cle public slgnlfle que n'lmporLe qul peuL envoyer a l'ob[eL de la classe le message
writeCoordinates() qul declenchera la meLhode.
Le moL cle void slgnlfle que ceLLe meLhode ne renvole pas de resulLaL. C'esL une procdure
par opposlLlon a une fonct|on qul renvole Lou[ours un resulLaL.
Mme sl la meLhode ne renvole pas de resulLaL, l'envol de message durera ce que dure
la meLhode. 1anL que la meLhode ne sera pas flnle, l'lnsLrucLlon
p.writeCoordinates() ne se Lermlnera pas.
16
L'appel a System.out.print() provoque l'afflchage de son argumenL dans un espace
d'afflchage dur l'ecran que l'on appelle la Conso|e. vous verrez cela mleux lors des 1s.
L'appel a System.out.println() provoque l'afflchage de son argumenL dans la
Console puls un sauL de llgne dans la Console.
Sl nous lanons l'execuLlon de ce programme, nous allons avolr des afflchages dans la Conso|e. La
Console dans ce polycople sera represenLe par une boiLe recLangulalre :
x = 0
y = 0
Cn a couLume de dlre que |'tat d'un ob[et esL represenLe par |a va|eur de ses attr|buts.
2.6. ketour sur |'|n|t|a||sat|on
!ava lnlLlallse les aLLrlbuLs d'un ob[eL avec des va|eurs par dfaut. Alnsl, nous avons vu qu'un aLLrlbuL
de Lype int sera lnlLlallse a 0. nous verrons qu'll en sera de mme pour les auLres Lypes d'aLLrlbuLs.
Le programmeur peuL voulolr lnlLlallser lul-mme les aLLrlbuLs avec des valeurs auLres que les valeurs
par defauL. our cela, ll fauL deflnlr un constructeur speclflque.
un constructeur se presenLe comme une meLhode qul a le mme nom que la classe avec
evenLuellemenL des parameLres. un consLrucLeur n'a aucun Lype de reLour.
Lxemple, lcl en gras :
public class Point
{
private int x ;
private int y ;
public Point(int x0, int y0)
{
x = x0 ;
y = y0 ;
}
public void writeCoordinates()
{
System.out.print(x = ) ;
System.out.println(x) ;
System.out.print(y = ) ;
System.out.println(y) ;
}
}
Cn volL que le consLrucLeur n'a pas de Lype de reLour eL qu'll possede deux arguments x0 eL y0 de
Lype int. Ces deux argumenLs se declare apres le nom du consLrucLeur enLre parenLheses eL separe
par des vlrgules.
17
Cn peuL alors creer un ob[eL de Lype Point en donnanL des valeurs aux argumenLs necessalres :
Point p = new Point(23,67) ;
noLons qu'une fols un consLrucLeur deflnl dans une classe, ll esL necessalre que la
creaLlon d'un ob[eL fasse appel a un consLrucLeur.
2.7. Un deux|me constructeur
ll esL posslble de deflnlr plusleurs consLrucLeurs dans une classe permeLLanL des
lnlLlallsaLlons dlfferenLes des aLLrlbuLs. La seule condlLlon esL que ces consLrucLeurs alenL
des parameLres dlfferenLs solenL en Lypes solenL en nombre.
Alnsl, on peuL deflnlr un nouveau consLrucLeur dans la classe Point, en gras cl-dessous :
public class Point
{
private int x ;
private int y ;
public Point(int x0, int y0)
{
x = x0 ;
y = y0 ;
}
public Point(double rho, double theta)
{
x = (int)(rho * Math.cos(theta)) ;
y = (int)(rho * Math.sin(theta)) ;
}
public void writeCoordinates()
{
System.out.print(x = ) ;
System.out.println(x) ;
System.out.print(y = ) ;
System.out.println(y) ;
}
}
uans ceLLe nouvelle verslon du consLrucLeur, les deux parameLres onL le Lype double qul esL celul
des nombres floLLanLs, une approxlmaLlon des nombres reels. nous uLlllsons les foncLlons coslnus eL
slnus sous la forme Math.cos() eL Math.sin(). nous revlendrons sur ceLLe noLaLlon. Llles
prennenL en argumenL un double qul esL un angle en radlans. Lnfln, la noLaLlon (int)() serL a
converLlr ce qul esL a la place du en un int, alors que c'esL a prlorl un double. une fols cela ecrlL,
ll esL posslble de creer un ob[eL avec :
Point p = new Point(12.12,1.34) ;
18
nous voyons que les nombres reels s'ecrlvenL comme aux LLaLs-unls avec un polnL a la place de
noLre vlrgule.
CommenL !ava cholslL-ll le bon consLrucLeur ? nous avons dlL que les consLrucLeurs dolvenL avolr des
argumenLs dlfferenLs solenL en nombre solenL en Lypes. !ava regarde donc les Lypes des argumenLs
eL cholslL le consLrucLeur en foncLlon des Lypes. Le consLrucLeur uLlllse lors de la creaLlon d'un ob[eL
esL deLermlne par les Lypes des argumenLs donnes a l'lnsLrucLlon new. Alnsl, par exemple :
new Point(23,67) ; uLlllsera un consLrucLeur ayanL deux int en argumenLs ,
new Point(10.62,1.6) ; uLlllsera un consLrucLeur ayanL deux double en argumenLs.
C'esL pour cela que les consLrucLeurs dolvenL Lre declares avec des argumenLs dlfferenLs solenL en
nombre solL en Lypes.
2.8. Un constructeur qu| appe||e un autre constructeur
ll esL posslble qu'un consLrucLeur uLlllse un auLre consLrucLeur. L'appel a un auLre
consLrucLeur se falL avec le moL cle this sulvl des argumenLs enLre parenLheses. Ce dolL
Lre la premlere lnsLrucLlon du consLrucLeur appelanL.
Alnsl, le second consLrucLeur cl-dessus peuL Lre reecrlL :
public Point(double rho, double theta)
{
this((int)(rho * Math.cos(theta)),(int)(rho * Math.sin(theta))) ;
}
lcl, le moL cle this falL reference au consLrucLeur ayanL deux int en argumenL.
2.9. Les types en Iava
1ouLe donnee manlpulee par le langage !ava possede un type. un Lype decrlL la naLure des donnees.
ar exemple, int esL un Lype qul decrlL les valeurs de Lype enLler. Lorsqu'un aLLrlbuL ou une varlable
esL declaree, le programmeur la declare avec un Lype. Cela slgnlfle que la l'aLLrlbuL ou la varlable ne
peuL conLenlr que des valeurs de Lype. Ln !ava, on dlsLlngue deux caLegorles de Lypes :
les types de bases aussl appelees types sca|a|res ,
les types rfrences.
2.10. Les types sca|a|res
nous avons de[a vu le Lype int. un aLLrlbuL ou une varlable de Lype int se declare alnsl :
int v ;
un attr|but de Lype int esL lnlLlallsee avec la valeur 0.
une var|ab|e de Lype int dolL Lre expllclLemenL lnlLlallsee :
int v = 0 ;
19
Cn dolL cholslr d'lnlLlallser une varlable lors de sa declaraLlon.
ll esL blen enLendu posslble d'lnlLlallser egalemenL les aLLrlbuLs lors de leurs declaraLlons.
volcl les dlfferenLs Lypes scalalres de !ava :
1ype S|gn|f|cat|on Va|eurs poss|b|es
char
CaracLere !eu de caracLeres unlcode noLes a, b, eLc.
byte
LnLler Lres courL -128 a 127
short
LnLler courL -32768 a 32767
int
LnLler -2147483648 a 2147483647
long
LnLler long -9223372036854775808 a 9223372036854775807
float
lloLLanL slmple preclslon
1.4*10
-45
3.4*10
38
(valeurs absolues mlnlmale eL maxlmale)
double
lloLLanL double preclslon
4.9*10
-324
1.7*10
308
(valeurs absolues mlnlmale eL maxlmale)
boolean
8oolean true ou false
Les aLLrlbuLs donL le Lype esL un Lype numerlque sonL lnlLlallsees avec la valeur zero. Les aLLrlbuLs de
Lype boolean sonL lnlLlallsees avec la valeur false.
2.10.1. Les oprat|ons ar|thmt|ques
!ava connaiL les prlnclpales operaLlons arlLhmeLlques sur les Lypes numerlques qul permeLLenL de
consLrulre des expresslons :
x * y (mulLlpllcaLlon)
x + y (addlLlon)
x y (sousLracLlon)
x / y (dlvlslon)
x % y ; (modulo)
(x + 2) * y ; (parenLheses)
noLons :
Les operaLeurs arlLhmeLlques foncLlonnenL egalemenL avec les Lypes float eL double a
l'excepLlon du modulo.
ll exlsLe de nombreuses subLlllLes concernanL l'arlLhmeLlque. Alnsl, par exemple, le produlL
d'un short par un int aura un resulLaL int. nous ne nous aLLarderons pas dessus.
Ln cas de douLe sur la manlere donL sera evalue une expresslon, ne pas heslLer a a[ouLer des
parenLheses.
20
2.10.2. Les oprateurs de compara|son
!ava connaiL les operaLeurs de comparalson donL le resulLaL esL un booleen :
x <= y (lnferleur ou egal)
x < y (lnferleur)
x == y (egallLe)
x != y (lnegallLe)
x > y (superleur)
x >= y (superleur ou egal)
Les operaLeurs d'egallLe eL d'lnegallLe ne foncLlonnenL qu'avec des Lypes scalalres. Ln
aucun cas, ll ne fauL les uLlllser avec des Lypes references.
A11LN1ICN ! Les operaLeurs d'egallLe eL d'lnegallLe ne foncLlonnenL pas avec les Lypes
float eL double. our LesLer l'egallLe de deux nombres floLLanLs f1 eL f2, on
uLlllsera (Math.abs(f1,f2) < 0.00001) qul slgnlfle que la valeur absolue de
la dlfference de f1 eL f2 esL lnferleur a 0.00001. our l'lnegallLe, on prendra la
negaLlon de ceLLe expresslon.
2.10.3. Les oprateurs |og|ques
!ava connaiL les Lrols prlnclpales operaLlons loglques qul aglssenL sur des booleens :
boolean b0 = (x < y) && (x > z) ; (con[oncLlon loglque)
boolean b1 = (x < y) || (x > z) ; (dls[oncLlon loglque)
boolean b2 = ! b1 ; (negaLlon loglque)
8appelons qu'en cas de douLe sur la manlere donL sera evalue une expresslon, ll ne fauL pas heslLer a
a[ouLer des parenLheses.
2.11. Les types rfrences
Supposons que T esL le nom d'une classe, on peuL declarer une varlable v de Lype reference sur des
ob[eLs de Lype T par :
T v ;
une Lelle varlable dolL conLenlr des references sur des ob[eLs de la classe T ou blen la valeur null.
Sl v conLlenL null alors v ne reference aucun ob[eL de Lype T.
1ouLe LenLaLlve d'envoyer un message a null se Lradulra par une erreur a l'execuLlon
du programme.
La varlable v esL lnlLlallsee avec la valeur null en ecrlvanL :
T v = null ;
21
Cn peuL egalemenL lnlLlallser la varlable v avec un ob[eL de Lype T en ecrlvanL :
T v = new T() ;
ou T() esL l'appel a un consLrucLeur de T.
2.11.1. Lnvo| de message
L'envol d'un message m(a1,,an) a un ob[eL de Lype reference r s'ecrlL :
r.m(a1,,an)
our qu'un Lel envol solL vallde, ll fauL que l'ob[eL r pulsse le recevolr eL y repondre. our cela, la
classe de l'ob[eL r dolL posseder une meLhode de nom m avec n parameLres ayanL les bons Lypes : le
i-leme parameLre de la meLhode dolL avolr le Lype de ai pour i varlanL de 1 [usqu'a n.
La meLhode peuL renvoyer une reponse ou pas.
Sl la meLhode ne renvole pas de reponse, c'esL-a-dlre que son Lype de reLour esL void, alors
l'envol de message s'ecrlL :
r.m(a1,,an) ;
Sl la meLhode renvole une reponse de Lype T, c'esL-a-dlre que son Lype de reLour esL T, on
dolL alors recuperer la reponse dans une varlable de Lype T :
v = r.m(a1,,an) ;
noLons que le Lype T peuL Lre un Lype scalalre ou un Lype reference.
Lxemp|e. Cn peuL voulolr une classe Point avec un meLhode shift(int dx, int dy) qul
demande au polnL de se deplacer de dx sulvanL l'axe des x eL dy sulvanL l'axe des y :
public class Point
{
/** Point coordinates */
private int x ;
private int y ;
/** Constructor */
public Point(int x0, int y0)
{
x = x0 ;
y = y0 ;
}
/** To shift a Point */
public void (int dx, int dy)
{
x = x + dx ;
y = y + dy ;
}
}
La meLhode shift(int dx, int dy) ne renvole aucun resulLaL. Cn peuL donc ecrlre :
p.shift(10,15) ;
22
ou p esL une varlable de Lype reference sur des Point.
Lxemp|e. lmaglnons que la classe Point alL une meLhode double distanceToOrigin() donL
la foncLlon esL de calculer la dlsLance du Point a l'orlglne. Cn peuL la programmer alnsl :
public class Point
{
/** Get distance to origin. */
public double distanceToOrigin()
{
return Math.sqrt(x*x + y*y) ;
}
}
8appelons que Math.sqrt(x) calcule la raclne carree de x. CeLLe meLhode n'a pas de parameLre.
Llle renvole une valeur de Lype double. Cn dolL donc ecrlre :
double d = p.distanceToOrigin() ;
ou p esL une varlable de Lype reference sur des Point.
2.11.2. Syntaxe des mthodes
L'en-LLe d'une meLhode esL composee de :
le moL cle public ou blen private ,
le Lype de la reponse ou void s'll n'y a pas de reponse ,
le nom de la meLhode ,
la parenLhese ouvranLe ( ,
la llsLe des parameLres avec leurs noms eL leurs Lypes ,
la parenLhese fermanLe ) .
L'en-LLe d'une meLhode esL aussl appele la s|gnature de la meLhode.
2.12. L'encapsu|at|on des attr|buts
Les aLLrlbuLs d'un ob[eL represenLenL son eLaL. Les aLLrlbuLs dolvenL Lou[ours Lre declares avec le
moL cle private. ue ceLLe manlere, seul l'ob[eL lul-mme peuL y acceder. Cn parle alors
d'encapsulaLlon des donnees.
Lxemp|e. La classe Point qul represenLe des polnLs du plan avec deux aLLrlbuLs de Lype scalalre :
public class Point
{
private int x ;
private int y ;
}
Lxemp|e. La classe Segment qul represenLe des segmenLs du plan avec deux aLLrlbuLs de Lype
references sur des ob[eLs :
23
public class Segment
{
private Point a ;
private Point b ;
}
L'encapsu|at|on de donnes esL fondamenLale en lnformaLlque.
Sl les donnees ne sonL pas encapsulees, n'lmporLe quel auLre ob[eL peuL les modlfler eL cela peuL
condulre a des lncoherences. Sl l'on deslre qu'un auLre ob[eL pulsse modlfler des aLLrlbuLs, ll fauL
fournlr une meLhode qul permeL de modlfler ces aLLrlbuLs. ue mme, sl l'on veuL pouvolr consulLer
les aLLrlbuLs, ll fauL fournlr une meLhode qul permeL d'en connaiLre la valeur. L'encapsulaLlon des
donnees concerne la consulLaLlon des donnees eL les modlflcaLlons des donnees.
2.12.1. Les accesseurs ou mthodes d'accs
Sl l'on deslre connaiLre la valeur d'un aLLrlbuL, ll fauL le demander a l'ob[eL. our cela, on deflnlL une
meLhode speclflque appelee un qettet car le nom de la meLhode commence hablLuellemenL par le
moL get. un qettet peuL Lre aussl appele accesseur ou meLhode d'acces.
Lxemp|e. uans la classe Point, on peuL deflnlr deux qettets :
public class Point
{
public int getX()
{
return x ;
}
public int getY()
{
return y ;
}
}
Cn ne meLLra des qettets dans une classe que sl c'esL vralmenL necessalre.
Lxemp|e. renons une classe Rectangle censee represenLer les recLangles du plan paralleles aux
axes. Celul-cl aura Lrols aLLrlbuLs : un Point qul represenLera la poslLlon de son coln superleur
gauche, deux int qul sonL ses largeur eL hauLeur.
24
public class Rectangle
{
private Point position ;
private int width ;
private int height ;
public Rectangle(int x, int y, int w, int h)
{
position = new Point(x,y) ;
width = w ;
height = h ;
}
public Point getPosition()
{
return position ;
}
public int getWidth()
{
return width ;
}
public int getHeight()
{
return height ;
}
}
Cn uLlllse alors les qettets alnsl :
Rectangle rectangle = new Rectangle(10,20,25,10) ;
int surface = rectangle.getWidth() + rectangle.getHeight() ;
Les qettets sonL formes du nom de l'aLLrlbuL preflxe par get. Cuand l'aLLrlbuL esL de
Lype boolean, on preflxera le nom de l'aLLrlbuL par is pluLL que par get.
2.12.2. Les mutateurs ou mthodes de mod|f|cat|on
our modlfler un aLLrlbuL d'un ob[eL, ll fauL le lul demander. our cela, on deflnlL une meLhode
speclflque appelee un settet car le nom de la meLhode commence generalemenL par set. un settet
esL aussl appele un muLaLeur ou une meLhode de modlflcaLlon.
Lxemp|e. uans la classe Point, on peuL deflnlr deux settets permeLLanL de modlfler les deux
aLLrlbuLs x eL y :
23
public class Point
{
private int x ;
private int y ;
public final void setX(int newX)
{
x = newX ;
}
public void setY(int newY)
{
y = newY ;
}
}
2.12.3. L'encapsu|at|on des donnes
L'encapsulaLlon des donnees, que l'on peuL appeler encapsulaLlon des aLLrlbuLs en programmaLlon
orlenLe ob[eL, esL un prlnclpe Lres lmporLanL en lnformaLlque. 1ous les aLLrlbuLs dolvenL Lre quallfles
avec le moL cle private qul slgnlfle que les aLLrlbuLs ne peuvenL Lre consulLes ou modlfles que
depuls les meLhodes de l'ob[eL. Les ralsons de ce prlnclpe sonL mulLlples eL nous allons en volr
quelques-unes.
2.12.4. Lncapsu|at|on : va||der |es va|eurs des attr|buts
Avolr des seLLers permeL de conLrler la valldlLe des valeurs que l'on veuL donner a un
aLLrlbuL.
Lxemp|e. lmaglnons une classe Human permeLLanL de represenLer des humalns avec une meLhode
setAge qul permeL de speclfler l'ge de l'humaln.
public class Human
{
private int age ;
pubic boolean setAge(int newAge)
{
if (age >= 0 && age < 150) {
age = newAge ;
return true ;
}
return false ;
}
}
La meLhode setAge conLrle la valldlLe de son parameLre. Sl sa valeur esL correcLe, elle l'aLLrlbue a
l'aLLrlbuL age eL renvole le booleen true. uans le cas conLralre, elle renvole le booleen false. La
valeur de reLour permeL de savolr ce qul s'esL passe.
26
2.12.S. Lncapsu|at|on : cohrence des donnes
L'encapsulaLlon des aLLrlbuLs permeL de preserver la coherence des sLrucLures de
donnees.
Lxemp|e. lmaglnons une classe Vector permeLLanL de represenLer des vecLeurs ayanL l'orlglne
comme exLremlLe. Les vecLeurs sonL caracLerlses par leurs coordonnees. CependanL, nous
malnLenons un aLLrlbuL length qul conLlenL la longueur du vecLeur.
public class Vector
{
private int dx ;
private int dy ;
private double length ;
public Vector(int dx, int dy)
{
setDxDy(dx,dy) ;
}
public void setDxDy(int newX, int newY)
{
dx = newX ;
dy = newY ;
length = Math.sqrt(dx*dx + dy*dy) ;
}
}
Sur ceL exemple, on volL que l'on a regroupe les deux settets en un seul qul modlfle a la fols les
aLLrlbuLs dx eL dy de l'ob[eL. Ce seLLer, en plus de modlfler dx eL dy, modlfle egalemenL l'aLLrlbuL
length. Ln effeL, chaque fols que dx eL dy sonL modlfles, ll fauL obllgaLolremenL modlfler l'aLLrlbuL
length. Ln uLlllsanL un settet pour les aLLrlbuLs de ceL ob[eL, nous preservons la coherence de ceL
ob[eL. Sl les aLLrlbuLs dx eL dy eLalenL lalsses llbre d'acces, on pourralL modlfler les aLLrlbuLs eL
neanmolns oubller de modlfler length.
2.12.6. Lncapsu|at|on : cohrence de |'app||cat|on
L'encapsulaLlon des aLLrlbuLs alde a garanLlr la coherence de l'appllcaLlon.
lmaglnons un ensemble de classes d'ob[eLs geomeLrlques correspondanL a des flgures en cours
d'edlLlon dans un edlLeur graphlque. 1ouLe modlflcaLlon des caracLerlsLlques d'une flgure, c'esL-a-
dlre ce qul esL represenLe par ses aLLrlbuLs, dolL enLrainer un rafraichlssemenL de l'afflchage dans la
fenLre d'edlLlon. Sl ce rafraichlssemenL n'esL pas falL, l'appllcaLlon sera lncoherenLe. Ln effeL, les
donnees Lels qu'elles sonL en memolre (ce que l'on appelle |e mod|e) ne seronL pas refleLee par
l'afflchage (ce que l'on appelle |a vue). Ce sonL les meLhodes de modlflcaLlon des aLLrlbuLs des ob[eLs
graphlques qul seronL en charge de reallser un rafraichlssemenL de la fenLre d'edlLlon.
27
2.12.7. Lncapsu|at|on : transparence des m|ses en muvre
une classe presenLe l'lnLerface de ses ob[eLs avec le monde exLerleur. Les aLLrlbuLs sonL caches car lls
sonL quallfles avec le moL cle private. Les meLhodes sonL, sauf sl c'esL lnuLlle, vlslbles car
quallflees avec le moL cle public.
L'encapsulaLlon des aLLrlbuLs permeL de modlfler la mlse en ouvre des meLhodes de
manlere LransparenLe. Cela slgnlfle que l'on peuL donner des mlses en ouvre dlfferenLes
sans changer la semanLlque (le sens) des meLhodes.
Supposons que l'on alL souvent besoln de connaiLre la longueur d'un vecLeur. Cn lmplemenLera la
longueur par un aLLrlbuL que l'on recalculera chaque fols que le vecLeur changera.
public class Vector
{
private int dx ;
private int dy ;
private double length ;
public double getLength()
{
return length ;
}
public void setDxDy(int newDx, int newDy)
{
dx = newDx ;
dy = newDy ;
length = Math.sqrt(dx*dx + dy*dy) ;
}
}
ue ceLLe manlere, quand on veuL connaiLre la longueur d'un vecLeur, on donne dlrecLemenL l'aLLrlbuL
eL c'esL Lres raplde. MalnLenanL, supposons que l'on alL rarement besoln de connaiLre la longueur
d'un vecLeur. uans ce cas, pluLL que de calculer la longueur dans un aLLrlbuL de l'ob[eL a chaque
changemenL du vecLeur, on ne recalculera la longueur que lorsqu'on la demandera :
public class Vector
{
private int dx ;
private int dy ;
public double getLength()
{
return Math.sqrt(dx*dx + dy*dy) ;
}
public void setDxDy(int newDx, int newDy)
{
dx = newDx ;
dy = newDy ;
}
}
28
arce que les donnees onL eLe blen encapsulees dans la classe Vector, on peuL uLlllser l'une ou
l'auLre lmplemenLaLlon de la classe de manlere LransparenLe. Ln effeL, les deux classes lmplemenLanL
la classe Vector presenLenL la mme |nterface. Cela slgnlfle que ces deux classes presenLenL les
mmes meLhodes a leurs uLlllsaLeurs. 8len enLendu, ces meLhodes sonL lmplemenLees de manlere
dlfferenLe. L'usage d'une classe ou de l'auLre dependra du programme qul l'uLlllsera selon que l'on
aura besoln de connaiLre souvenL ou raremenL la longueur des vecLeurs.
Sl les donnees sonL correcLemenL encapsulees dans une classe, l'uLlllsaLeur de la classe
n'a pas besoln de savolr commenL sonL sLrucLurees les donnees eL commenL les
meLhodes sonL programmees a l'lnLerleur des ob[eLs de la classe.
2.13. Le mot c| th|s
Lorsqu'une meLhode esL execuLee, c'esL l'ob[eL qul execuLe la meLhode. uans ceLLe
meLhode, le moL cle this esL une reference sur l'ob[eL qul execuLe la meLhode.
8eprenons la classe Vector avec un nouveau consLrucLeur :
public class Vector
{
private int dx ;
private int dy ;
public Vector(Point a, Point b)
{
dx = b.getX() a.getX() ;
dy = b.getY() a.getY() ;
}
}
nous la compleLons avec la classe Point eL une nouvelle meLhode :
public class Point
{
public Vector vectorTo(Point other)
{
return new Vector(this,other) ;
}
}
Cn volL lcl l'usage du moL cle this pour calculer le vecLeur qul va du polnL couranL au polnL
argumenL. ar exemple, on peuL ecrlre :
Point p1 = new Point(23,10) ;
Point p2 = new Point(15,30) ;
Vector v = p1.vectorTo(p2) ;
29
2.14. orte des dc|arat|ons de var|ab|es
Lors de l'ecrlLure d'une classe, on dlsLlngue dlfferenLs Lypes de declaraLlons que nous pouvons volr
dans l'exemple cl-dessous :
public class Test
{
private int x ; /* dclaration dattribut */
public void f(int y) /* dclaration de paramtre */
{
int z = 0 ; /* declaration de variable locale un bloc */
z = x + y ;
}
}
une declaraLlon d'aLLrlbuLs, de parameLre ou de varlable a une porte. C'esL la zone
du programme ou la declaraLlon esL vallde. C'esL donc la parLle du programme ou
l'on peuL uLlllser l'aLLrlbuL, le parameLre ou la varlable declaree.
La porLee d'une declaraLlon d'aLLrlbuL esL la classe enLlere. un aLLrlbuL esL donc accesslble dans
LouLes les meLhodes de la classe.
La porLee d'une declaraLlon de parameLre de meLhode esL la meLhode enLlere. La varlable parameLre
esL creee au debuL de l'execuLlon de la meLhode eL elle dlsparaiL a la fln de l'execuLlon de la meLhode.
La porLee d'une declaraLlon de varlable locale a un bloc eL la parLle du bloc slLuee enLre la declaraLlon
eL la fln du bloc. La varlable esL creee au momenL ou ceLLe declaraLlon a eLe falLe eL elle dlsparaiL a la
fln du bloc.
2.1S. ketour sur |e mot c| th|s
ll peuL arrlver qu'une declaraLlon de parameLre masque une declaraLlon d'aLLrlbuL.
Lxemple.
public class Point
{
private int x ;
private int y ;
public Point(int x, int y)
{
x = ; // quel est cet x ?
30
uans le consLrucLeur Point(int x, int y), on volL un x. Ce x esL-ll le x parameLre du
consLrucLeur ou blen le x aLLrlbuL ? Ln falL, LouLe uLlllsaLlon de x dans le consLrucLeur correspond au
parameLre x car la declaraLlon du parameLre prend le pas sur la declaraLlon d'aLLrlbuL.
Mals alors, commenL uLlllser l'aLLrlbuL x ? 1ouL slmplemenL en uLlllsanL le moL cle this eL en
ecrlvanL this.x. Alnsl, le consLrucLeur peuL s'ecrlre :
public class Point
{
private int x ;
private int y ;
public Point(int x, int y)
{
this.x = x ;
this.y = y ;
}
}
Alnsl, this.x falL reference a l'aLLrlbuL x Landls que le x seul falL reference au parameLre x. ll en
esL de mme pour y.
uans les consLrucLeurs, ll esL recommande d'ecrlre les consLrucLeurs comme celul cl-
dessus en uLlllsanL this pour referencer l'aLLrlbuL.
2.16. assage de paramtres
Le parameLre declare dans l'en-LLe de la meLhode esL appele paramtre forme|.
La valeur uLlllsee lors de l'envol de message esL appelee paramtre effect|f.
Lorsque l'ob[eL reolL un message correspondanL a l'une de ses meLhodes, le parameLre formel esL
lnlLlallsee avec la valeur du parameLre effecLlf. Cn dlL que !ava praLlque le passage de paramtre par
va|eur.
Conslderons la classe Point :
public class Point
{
private int x ;
private int y ;
public void setXY(int x0, int y0)
{
x = x0 ;
y = y0 ;
}
}
eL les lnsLrucLlons sulvanLes ou p esL une varlable reference sur un Point :
31
int u = 5 ;
p.setXY(u,u+5) ;
Lors de l'execuLlon de l'lnsLrucLlon p.setXY(u,u+5), !ava cree LemporalremenL deux varlables
x0 eL y0 correspondanL aux parameLres formels de la meLhode. Ces deux varlables sonL alors
lnlLlallsees avec les valeurs des parameLres effecLlfs qul sonL lcl 5 eL 6. uls la meLhode esL execuLee.
LL enfln, les varlables Lemporalres dlsparalssenL.
2.16.1. Lxemp|e de passage de types sca|a|res
SolL la classe Point :
public class Point
{
public void setX(int x0)
{
x = x0 ;
}
}
Cn suppose que p esL une varlable reference sur un Point.
Sl l'on ecrlL :
p.setX(3) ;
la valeur du parameLre effecLlf 3 esL 3 eL le parameLre formel x0 esL lnlLlallsee avec ceLLe valeur.
Sl l'on ecrlL :
p.setX(3 + 4) ;
la valeur du parameLre effecLlf 3 + 4 esL 7 eL le parameLre formel x0 esL lnlLlallsee avec ceLLe
valeur.
Sl l'on ecrlL :
int u = 10 ;
p.setX(u) ;
la valeur du parameLre effecLlf u esL 10 eL le parameLre formel x0 esL lnlLlallsee avec ceLLe valeur.
Sl l'on ecrlL :
int u = 8 ;
p.setX(u + 1) ;
la valeur du parameLre effecLlf u + 1 esL 9 eL le parameLre formel x0 esL lnlLlallsee avec ceLLe
valeur.
32
2.16.2. Lxemp|e de passage de types rfrences
SolL la classe Point :
public class Point
{
public double distanceTo(Point other)
{
int dx = x other.getX() ;
int dy = y other.getY() ;
return Math.sqrt(dx*dx + dy*dy) ;
}
}
Cn suppose que p esL une varlable reference sur un Point.
Sl l'on ecrlL :
double d = p.distanceTo(null) ;
la valeur du parameLre effecLlf null esL null eL le parameLre formel other esL lnlLlallse avec
ceLLe valeur qul provoquera une erreur.
Sl l'on ecrlL :
Point q = null ;
double d = p.distanceTo(q) ;
la valeur du parameLre effecLlf q esL null eL le parameLre formel other esL lnlLlallse avec ceLLe
valeur qul provoquera une erreur.
Sl l'on ecrlL :
Point q = new Point(10,12) ;
double d = p.distanceTo(q) ;
la valeur du parameLre effecLlf q esL une reference sur le polnL cree par l'lnsLrucLlon new eL le
parameLre formel other esL lnlLlallse avec la mme reference.
Sl l'on ecrlL :
double d = p.distanceTo(new Point(13,34)) ;
la valeur du parameLre effecLlf new Point(13,34) esL une reference sur le polnL cree par
l'lnsLrucLlon new eL le parameLre formel other esL lnlLlallsee avec la mme reference.
2.17. 8|ocs d'|nstruct|ons
Cn noLe b|oc d'|nstruct|ons une sulLe d'lnsLrucLlons encadrees par les accolades { eL }.
La mlse en ouvre d'une meLhode esL Lou[ours reallsee par un bloc d'lnsLrucLlons. C'esL-a-dlre que
l'on meL les lnsLrucLlons de la meLhode a l'lnLerleur d'accolades.
33
2.18. Var|ab|es |oca|es
une var|ab|e |oca|e esL une varlable declaree a l'lnLerleur d'un bloc d'lnsLrucLlon.
La porLee de la declaraLlon d'une varlable locale esL la parLle du programme qul commence a
l'endrolL de la declaraLlon eL se Lermlne a l'accolade fermanLe du bloc d'lnsLrucLlons qul la conLlenL.
une declaraLlon de varlable locale peuL egalemenL masquer une declaraLlon d'aLLrlbuL. lcl aussl
l'aLLrlbuL resLe accesslble grce au moL cle this.
2.19. ketour sur |'ga||t
nous avons vu le LesL d'egallLe noLe x == y. Celul-cl foncLlonne unlquemenL avec les
Lypes scalalres dlscreLs : char, byte, int, long eL boolean.
ll ne foncLlonne pas avec les Lypes float eL double, volr 2.10.2. LL ll a une slgnlflcaLlon Lres
parLlcullere avec les Lypes references.
L'operaLeur == uLlllse avec un Lype reference slgnlfle que les deux operandes sonL
des references sur le mme ob[eL en memolre.
1esLer que deux varlables (de Lype reference) referencenL le mme ob[eL en memolre esL lnuLlle en
!ava. our LesLer que deux ob[eLs sonL egaux au sens large, les classes proposenL une meLhode
equal. Alnsl, pour LesLer l'egallLe de deux chaines de caracLeres s1 eL s2 (c'esL-a-dlre pour LesLer
qu'elles sonL composees des mmes caracLeres dans le mme ordre), on uLlllsera s1.equals(s2).
2.20. Convent|ons de nommage
Les noms des classes respecLenL les convenLlons sulvanLes :
premlere leLLre en ma[uscule ,
melange de mlnuscules, ma[uscules avec la premlere leLLre de chaque moL en ma[uscule ,
donner des noms expllclLes.
Les noms des varlables eL des aLLrlbuLs respecLenL les convenLlons sulvanLes :
premlere leLLre en mlnuscule ,
melange de mlnuscules, ma[uscules avec la premlere leLLre de chaque moL en ma[uscule ,
donner des noms expllclLes.
Cn evlLera les caracLeres speclaux, le soullgne _ par exemple.
33
3. Deux c|asses prdf|n|es, |es
tab|eaux
Ce chaplLre esL un chaplLre lnLermedlalre mals necessalre. nous allons presenLer deux classes de !ava
predeflnles eL Lres uLlles. Ces classes seronL uLlllsees dans nos exemples. redeflnles slgnlfle que !ava
les a de[a deflnles eL qu'll sufflL de le uLlllser. Ln Lheorle, ll n'esL pas besoln de connaiLre les classes
predeflnles par cour car la documenLaLlon se Lrouve sur lnLerneL ou sur voLre ordlnaLeur. Ln
praLlque, ll esL quand mme necessalre de connaiLre une parLle de quelques classes. ue mme, ll esL
egalemenL necessalre de connaiLre l'exlsLence de cerLalnes classes sans qu'll solL necessalre de
connaiLre leurs meLhodes.
Les langages de programmaLlon onL eLe lnvenLes pour que l'on pulsse programmer avec des
concepLs de haut n|veau qul n'exlsLenL pas sur un ordlnaLeur nu. ar exemple, les var|ab|es eL les
va|eurs types sonL de[a un concepL de hauL nlveau. Cuand ['ecrls :
double f = 1.23 ;
[e suppose LouL un mecanlsme pour represenLer les nombres floLLanLs en memolre eL Lre capable
de reallser des operaLlons arlLhmeLlques dessus. ue mme, le concepL d'ob[et eL celul assocle
d'envo| de message sonL des concepLs de Lres hauL nlveau.
arml ces concepLs de hauL nlveau proposes par les langages flgurenL egalemenL les sLrucLures de
donnees evoluees. ue ce polnL de vue, !ava esL un langage remarquable qul propose la pluparL des
sLrucLures de donnees connues en lnformaLlque. nous allons eLudler deux classes lmporLanLes :
la classe String qul permeL de Lravalller avec des chaines de caracLeres ,
la classe ArrayList qul esL une mlse en ouvre de Lables de donnees exLenslbles.
3.1. Les caractres
Les caracLeres admls dans un langage formenL le [eu de caractres (cbotset) du langage. uans celul
de !ava, on Lrouve :
les leLLres de l'alphabeL, ma[uscules eL mlnuscules, presenLes dans de nombreuses langues ,
les symboles de poncLuaLlon ,
les symboles speclflquemenL lnformaLlques, volr voLre clavler ,
le caracLere espace, la LabulaLlon eL le sauL de llgne ,
36
des caracLeres non vlslbles que vous decouvrlrez en praLlquanL l'lnformaLlque.
La manlere donL les caracLeres sonL represenLes en memolre s'appelle l'encodage (eocoJloq). Ln
!ava, ll fauL deux ocLeLs en memolre pour represenLer un caracLere.
3.2. Les cha|nes de caractres
une chaine de caracLeres esL slmplemenL une sulLe de caracLeres ou chaque caracLere falL parLle du
[eu de caracLeres du langage. Lxemple : java esL une chaine de caracLeres. Les chaines de
caracLeres beneflclenL d'une noLaLlon speclflque. uans le langage de programmaLlon !ava, eL dans
presque Lous les langages, une chaine de caracLeres s'ecrlL enLre des double-quoLe (").
Lxemp|e :
"java"
"java is easy"
sonL des chaines de caracLeres.
Les chaines de caracLeres sonL des ob[ets de la classe String.
La classe SLrlng esL predeflnle en !ava.
Lxemp|e :
String s1 = null ; // a string initialized with null
String s2 = "java" ; // a string initialized with "java"
nous allons examlner la documenLaLlon de la classe String.
our obLenlr la documenLaLlon de la classe String, prenez voLre navlgaLeur prefere
eL voLre moLeur de recherche prefere, puls enLrez la recherche : Java SE7 String
La documenLaLlon que vous allez Lrouver esL une documenLaLlon au formaL [avadoc.
une documenLaLlon au formaL [avadoc esL un flchler P1ML consLrulL a parLlr du flchler de
code source !ava pourvu que l'on alL mls des commenLalres approprles dans le flchler de
code source. La producLlon de flchler [avadoc n'esL pas au programme
3
.
uans une documenLaLlon au formaL [avadoc, on Lrouve :
une premlere parLle qul monLre le package auquel apparLlenL la classe ,
une deuxleme parLle qul donne une descrlpLlon generale des ob[eLs de la classe eL de
commenL on dolL les uLlllser ,
une Lrolsleme parLle qul donne une descrlpLlon succlncLe des meLhodes eL des aLLrlbuLs de la
classe ,
3
La producLlon de flchler [avadoc n'esL pas Lres compllquee. Cuelques recherches sur lnLerneL vous
lndlqueronL commenL falre.
37
une quaLrleme parLle qul donne une descrlpLlon deLalllee des meLhodes eL des aLLrlbuLs de la
classe.
La documenLaLlon des meLhodes se llL en deLall.
Lxemp|e. La documenLaLlon de la meLhode charAt.
La documenLaLlon succlncLe nous dlL :
la meLhode charAt permeL de renvoyer le caracLere donne d'une chaine donne pare son lndex.
Mals ceLLe documenLaLlon esL Lres falble : l'lndex du premler caracLere esL-ll zero ou un ? que se
passe-L-ll sl l'lndex en argumenL esL plus grand que la longueur de la chalne ? Ln falL, ceLLe
documenLaLlon serL unlquemenL a se souvenlr du nom de la meLhode. our LouL savolr sur la
meLhode, ll fauL llre la documenLaLlon deLalllee :
La, on peuL volr que l'lndex du premler caracLere esL 0. uonc :
String s = "java" ;
s.charAt(0) retournera 'j'
s.charAt(1) retournera 'a'
s.charAt(2) retournera 'v'
s.charAt(3) retournera 'a'
Ln falL, l'lndex esL comprls enLre 0 eL s.length()-1 ou length() esL une meLhode de la classe
Srting qul reLourne la longueur de la chaine, c'esL-a-dlre son nombre de caracLeres. Cue se passe-
L-ll sl l'lndex en argumenL n'esL pas enLre ces bornes ? uans ce cas, la documenLaLlon nous dlL que la
meLhode |ve une except|on de Lype IndexOutOfBound.
nous n'avons pas encore vu les excepLlons. CerLalnes meLhodes declarenL qu'elles
peuvenL lever (throw) des excepLlons. Lever une excepLlon esL slmplemenL
declencher une erreur qul se Lradulra par l'arrL du programme eL l'afflchage d'un
message d'erreur. nous verrons cela dans un prochaln chaplLre eL nous verrons que le
programmeur peuL LralLer les excepLlons.
nous vous conselllons d'aller volr les auLres meLhodes de la classe String pour les examlner.
38
3.3. Lcr|re dans |a conso|e
La console esL une peLlLe zone de l'envlronnemenL Lcllpse.
our ecrlre un ob[eL s dans la console, on ecrlra :
System.out.print(s) ;
Sl s esL une chaine de caracLeres, les caracLeres de la chaine sonL afflche dans la console mals sans
les double-quoLe ("). Sl s esL une donnee de l'un des Lypes scalalres, on obLlenL l'afflchage du Lype
scalalre en base 10 sl c'esL un Lype numerlque ou blen true eL false sl c'esL le Lype boolean. Sl
s esL une donnee d'un Lype reference (auLre que String), on volL apparaiLre le nom de la classe,
sulvl du caracLere @, sulvl de l'adresse en memolre de l'ob[eL.
Lxemp|e. Supposons que l'on alL une classe olnL eL que l'on ecrlve :
System.out.print(new Point(12,34)) ;
L'afflchage dans la console monLrera :
Point@4b71bbc9
Sl l'on deslre afflcher un reLour a la llgne apres l'afflchage de l'argumenL, on uLlllsera println au
lleu de print. Sl l'on ecrlL :
System.out.print(123) ;
System.out.println("abc") ;
System.out.println("def") ;
on obLlendra sur la console :
123abc
def
La noLaLlon System.out esL une noLaLlon pour une var|ab|e de c|asse. nous verrons
cela dans un prochaln chaplLre. System.out esL une varlable de classe de Lype
PrintStream qul possede les meLhodes print eL println.
3.4. L'oprateur + de concatnat|on de cha|nes
L'operaLeur + peuL prendre deux chaines de caracLeres en parameLres eL reallse leur concaLenaLlon :
String s1 = "java" ;
String s2 = "coffee" ;
System.out.println(s1 + " " + s2) ;
afflchera :
39
java coffee
La concaLenaLlon des argumenLs peuL aussl Lre obLenue grce a la meLhode concat :
System.out.println(s1 + s2) ;
System.out.println(s1.concat(s2)) ;
afflchera :
javacoffee
javacoffee
ll esL slmplemenL plus faclle d'uLlllser l'operaLeur +.
3.S. La documentat|on Iava
La documenLaLlon des classes !ava esL accesslble sur lnLerneL ou en local chez vous sur voLre
ordlnaLeur sl vous avez lnsLalle l'envlronnemenL de developpemenL !ava. our y acceder sur lnLerneL,
ll sufflL d'enLrer dans voLre navlgaLeur avec voLre moLeur de recherche prefere la chaine :
Java SE7 <classe>
ou <classe> esL le nom de la classe donL on recherche la documenLaLlon. Ln foulllanL dans les
premlers resulLaLs, speclalemenL ceux du slLe Cracle, vous allez Lrouver la documenLaLlon. La
documenLaLlon esL au formaL [avadoc comme expllque en secLlon 3.2.
ll n'esL pas necessalre de connaiLre les classes predeflnles par cour. ll esL en revanche lnLeressanL de
connaiLre les prlnclpales classes eL une parLle de leurs meLhodes. ll esL LouL aussl lnLeressanL de
savolr les noms des prlnclpales classes. ar exemples les classes dlLes Iovo collectloos ltomewotk,
que nous verrons, sonL des classes donL ll fauL au mlnlmum connaiLre le nom.
3.6. La c|asse ArrayL|st
La classe ArrayList esL une classe parameLree par un auLre Lype. Cn dlL que l'on veuL une
ArrayList d'ob[eL de Lype T eL on noLe cecl ArrayList<T>. Sl T esL une classe, un ob[eL de la
classe ArrayList<T> esL une llsLe de references sur des ob[eLs de la classe T.
une classe qul esL parameLrable par un Lype esL appelee une c|asse gnr|que.
Cn cree une llsLe de Lype ArrayList<T> avec l'lnsLrucLlon new :
ArrayList<T> list = new ArrayList<T>() ;
CeLLe llsLe se cree avec une longueur nulle. Llle esL vlde. Mals elle s'allongera auLomaLlquemenL sl
necessalre. Les elemenLs de la llsLe sonL numeroLes a parLlr de 0.
renons l'exemple d'une ArrayList de String. Cn peuL la monLrer alnsl :
40
La longueur de la llsLe de Lype ArrayList<T> esL modlflee par les meLhodes :
boolean add (T t)
boolean add(int index, T t)
boolean remove(int index)
eLc.
ll fauL falre aLLenLlon aux erreurs concernanL les lndex. un lndex lnferleur a 0 ou superleur a la
longueur de la llsLe provoquera une excepLlon.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 ArrayList. Cherchez la documenLaLlon d'ArrayList eL
examlnez-la.
3.7. Les tab|eaux
Les Lableaux, ottoys en anglals, ne sonL pas des ob[eLs mals une sLrucLure de donnees
ordlnalre que l'on Lrouve dans Lous les langages de programmaLlon.
un Lableau esL l'equlvalenL d'une tab|e de ta|||e f|xe conLenanL des valeurs d'un Lype donne. La Lallle
de la Lable esL appelee sa d|mens|on. Le Lype Lableau esL un type gnr|que. lls ne sonL pas
exLenslbles comme le sonL les ArrayList.
Cn preferera Lou[ours l'uLlllsaLlon d'un ArrayList a l'uLlllsaLlon de Lableaux.
un Lableau peuL conLenlr des valeurs scalalres de Lype int, double, boolean, eLc. ll peuL
egalemenL conLenlr des references sur des ob[eLs d'un Lype donne.
une varlable de Lype Lableau se declare en falsanL sulvre le Lype des elemenLs du Lableau par des
crocheLs []. Lxemple :
String[] names ; // un tableau de rfrences sur des String
int[] values ; // un tableau de valeurs de type int
une varlable de Lype Lableau dolL Lre lnlLlallsee en creanL un Lableau. Slnon, un acces a un elemenL
du Lableau provoquera une erreur. L'lnlLlallsaLlon se falL avec l'lnsLrucLlon new sulvl du Lype des
elemenLs du Lableau sulvl de la dlmenslon enLre crocheL. Lxemple :
41
String[] names = new String[10] ; // dimension 10
int[] values = new int[5] ; // dimension 5
La dlmenslon du Lableau esL cholsle a a creaLlon du Lableau. Llle ne peuL plus Lre modlfle.
Les elemenLs d'un Lableau de dlmenslon n sonL numeroLes de 0 a n-1. Le numero d'un elemenL
dans un Lableau esL appele son |nd|ce. our acceder a un elemenL du Lableau a parLlr de son lndlce,
on falL sulvre le nom de la varlable de Lype Lableau du crocheL ouvranL, de l'lndlce eL du crocher
fermanL.
Lxemp|e. Sl l'on a declare eL lnlLlallse la varlable names :
String[] names = new String[10] ;
Cn peuL acceder a l'elemenL d'lndlce 7 avec la noLaLlon names[7] :
names[7] = "java" ;
System.out.println("names[7] = + names[7]) ;
3.8. Les c|asses prdf|n|es
une des caracLerlsLlques de !ava esL d'Lre accompagne par de Lres nombreuses classes predeflnles.
LL ll exlsLe egalemenL de nombreuses blblloLheques de classes developpees dans les unlverslLes ou
dans des enLreprlses. Cn les Lrouve en general sur lnLerneL.
ue falL, lorsque l'on dolL programmer en !ava, ll fauL au prealable rechercher sur lnLerneL le
programme que l'on veuL ecrlre. lmaglnons que l'on veullle envoyer des e-malls grce a un
programme !ava, on uLlllsera son navlgaLeur prefere eL son moLeur de recherche prefere pour
rechercher la chaine :
Java how to send mail
Sl l'on deslre consLrulre des flchlers Lxcel, on cherchera :
Java how to build Excel file
uans chacun des cas, on Lrouvera une blblloLheque a Lelecharger eL un mode d'emplol.
43
4. rogrammer |es mthodes
uans ce chaplLre, nous allons commencer a programmer serleusemenL en !ava. our cela, ll va nous
fallolr apprendre la programmat|on |mprat|ve. Ln effeL, les meLhodes se programmenL en uLlllsanL
ce paradlgme de programmaLlon.
nous avons vu que le prlnclpe de l'orlenLe ob[eL esL qu'un programme esL consLlLue d'ob[eLs qul
s'envolenL des messages, avec de posslbles lnLeracLlons de l'humaln par l'lnLermedlalre du clavler, de
la sourls ou d'auLres perlpherlques de l'ordlnaLeur. La recepLlon d'un message provoque l'execuLlon
d'une meLhode de l'ob[eL. Lorsque l'on programme une meLhode de l'ob[eL, on programme des
ordres, plus preclsemenL des |nstruct|ons, que l'ob[eL dolL execuLer lorsqu'll reolL le message auquel
correspond la meLhode.
4.1. Les types d'|nstruct|ons
Les lnsLrucLlons peuvenL Lre :
ues lnsLrucLlons slmples:
o AffecLaLlon d'une varlable.
o Lnvol de message.
o 1ermlnalson d'une meLhode.
ues lnsLrucLlons composees:
o LxecuLlon condlLlonnelle d'une lnsLrucLlon.
o lLeraLlon conLrlee d'une lnsLrucLlon.
o SequencemenL d'lnsLrucLlons (bloc d'lnsLrucLlons).
Les lnsLrucLlons composees sonL aussl appelees structures de contr|e de |'excut|on car
elles permeLLenL au programmeur de conLrler ce qul dolL Lre execuLe eL quand cela
dolL Lre execuLe.
44
4.2. Les var|ab|es |oca|es
Les varlables locales sonL declarees dans les meLhodes.
Les varlables locales aux meLhodes ne sonL pas lnlLlallsees par !ava. Seuls les aLLrlbuLs
des classes sonL lnlLlallses par !ava.
C'esL le programmeur qul esL responsable de l'lnlLlallsaLlon des varlables locales.
Lxemp|e.
{
int x = 0 ;
String s = null ;
}
Sl la varlable n'esL pas lnlLlallsee, elle conLlendra n'lmporLe quol.
4.3. Affectat|on d'une var|ab|e
ll esL posslble de modlfler la valeur d'une varlable locale ou d'un aLLrlbuL en uLlllsanL l'lnsLrucLlon
d'affecLaLlon. Sl x esL une varlable locale ou un aLLrlbuL de Lype T eL sl E esL une expresslon donL la
valeur a le mme Lype T, on peuL ecrlre une lnsLrucLlon d'affecLaLlon :
X = E ;
Lorsqu'll execuLe ceLLe lnsLrucLlon, l'ob[eL calcule la valeur de E puls la varlable v prend ceLLe valeur.
noLons que T peuL Lre un Lype scalalre ou reference.
Lxemp|e.
int x = 2 + 3 ;
int y = 0 ;
y = x * 2 ;
boolean b = (x == y) ;
Point p = new Point(10,10) ;
Point q = new Point(23,24) ;
Vector v = p.vectorTo(q) ;
4.4. Les commenta|res dans |es programmes
uans un programme, ll esL souvenL uLlle d'ecrlre des commenLalres dans les programmes. Ce ne sonL
pas des lnsLrucLlons mals unlquemenL des annoLaLlons LexLuelles desLlnees aux programmeurs qul
voudralenL comprendre commenL foncLlonne le programme. Les commenLalres sonL uLlles pour un
auLre programmeur qul deslreralL Lravalller sur le mme programme. Les commenLalres sonL uLlles
au programmeur lul-mme lorsqu'll dolL se rellre.
43
Les commenLalres dolvenL Lre concls, precls eL uLlles. Les commenLalres ne dolvenL pas dlre ce que
fonL les lnsLrucLlons car la lecLure des lnsLrucLlons permeL de deLermlner cela. Les commenLalres
dolvenL decrlre le pourquo| eL le comment.
1ouL ce qul se slLue enLre un slash-eLolle (/*) eL le prochaln eLolle-slash (*/) esL consldere comme
du commenLalre. Lxemple :
int count = 0 ; /* the photon counter */
ue mme, LouL ce qul se slLue enLre deux caracLere slash (//) eL la fln de la llgne esL consldere
comme du commenLalre. Lxemple :
count = count + 1 ; // a photon has been detected
8len enLendu, ll esL preferable de se passer de commenLalres en uLlllsanL des noms expllclLes.
Lxemple :
int photonsCount = 0 ;
4.S. La c|ass 8ankAccount
1ouL au long de ce chaplLre, nous allons examlner eL Lravalller sur une classe BankAccount. CeLLe
classe esL censee represenLer un compLe en banque dans le loglclel d'une banque. 8len enLendu, elle
esL Lres slmpllflee :
public class BankAccount
{
private String holder ;
private int number ;
private double amount ;
public BankAccount(String holder, int number)
{
this.holder = holder ;
this.number = number ;
this.amount = 0.0 ;
}
public void widthdraw(double value)
{
amount = amount value ;
}
public void deposit(double value)
{
amount = amount + value ;
}
}
CeLLe classe possede Lrols aLLrlbuLs propres au compLe en banque : le LlLulalre du compLe (holder),
le numero du compLe (number) eL la balance du compLe (amount). Ces aLLrlbuLs sonL lnlLlallses
dans le consLrucLeur. nous avons une meLhode withdraw qul permeL de reLlrer une cerLalne valeur
eL une meLhode deposit qul permeL de deposer une cerLalne valeur.
nous n'avons volonLalremenL pas mls de commenLalres pour des quesLlons de place.
46
4.6. L'|nstruct|on return
Lorsqu'une meLhode dolL repondre a un envol de message, elle le speclfle dans l'en-LLe de la
meLhode en ecrlvanL un Lype de reLour pluLL que le moL cle void. Alnsl, une meLhode donL l'en-
LLe esL :
public double getSurface() { }
esL une meLhode qul dolL renvoyer un double. double esL appele le type de retour de la
meLhode. our speclflerla valeur de la reponse, on uLlllse l'lnsLrucLlon return sulvle de la valeur de
la reponse. La valeur de la reponse esL une expresslon donL la valeur dolL avolr le Lype declare dans
l'en-LLe de la foncLlon.
Lxemp|e. Modlflons la classe BankAccount pour que les meLhodes withdraw eL deposit
renvolenL le solde du compLe apres l'operaLlon correspondanLe.
public class BankAccount
{
private String holder ;
private int number ;
private double amount ;
public BankAccount(String holder, int number)
{
this.holder = holder ;
this.number = number ;
this.amount = 0.0 ;
}
public double widthdraw(double value)
{
amount = amount value ;
return amount ;
}
public double deposit(double value)
{
amount = amount + value ;
return amount ;
}
}
L'execuLlon de l'lnsLrucLlon return dans une meLhode provoque la fln de l'execuLlon
de la meLhode.
Sl l'en-LLe de la meLhode speclfle un Lype de reLour, l'execuLlon de la meLhode dolL Lou[ours se
Lermlner par une lnsLrucLlon return approprlee. Sl des lnsLrucLlons sonL placees derrlere une
lnsLrucLlon return, elle ne seronL [amals execuLe eL !ava le slgnale. S'll exL posslble de Lermlner
l'execuLlon d'une meLhode avec un Lype de reLour sans execuLer d'lnsLrucLlon return, le
compllaLeur le slgnale aussl.
47
4.7. 8|ocs d'|nstruct|ons
Comme dlL en 2.17, un bloc d'lnsLrucLlons esL une sulLe d'lnsLrucLlons encadrees par des accolades.
LxecuLer un bloc d'lnsLrucLlons, c'esL execuLer les lnsLrucLlons qu'll conLlenL dans l'ordre ou elles sonL
ecrlLes. un bloc d'lnsLrucLlons esL une |nstruct|on compose. Sl nous revenons a noLre classe
BankAccount, nous voyons que les corps des meLhodes sonL des blocs d'lnsLrucLlons.
4.8. La c|asse 8ank
La classe Bank esL aussl une de nos classes d'exemple. Llle serL a represenLer une banque dans le
loglclel de banque. Llle conLlenL un aLLrlbuL accountsTable qul esL une ArrayList de
BankAccount.
La premlere llgne esL une dc|arat|on d'|mportat|on. Ln effeL, ArrayList esL une classe predeflnle
de !ava mals ne falL pas parLle des classes de base du langage. ll esL alors necessalre de l'lmporLer.
nous y revlendrons :
import java.util.ArrayList ;
public class Bank
{
private ArrayList<BankAccount> accountsTable ;
public Bank()
{
accountsTable = new ArrayList<BankAccount>() ;
}
}
8emarquons que l'aLLrlbuL accountsTable dolL Lre lnlLlallse dans le consLrucLeur.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 ArrayList. Cherchez la documenLaLlon d'ArrayList eL
examlnez-la.
4.9. kecherche d'un compte
A parLlr du nom du LlLulalre, on va devolr Lrouver un compLe en banque. our cela, on lnLerrogera
chacun des compLe de l'ob[eL Bank en uLlllsanL la meLhode sulvanLe que nous meLLons dans la classe
BankAccount :
public boolean belongsTo(String holder)
{
if (this.holder.equals(holder))
return true ;
return false ;
}
Cn remarque que dans ceLLe meLhode this.holder falL reference a l'aLLrlbuL holder Landls que
holder seul falL reference au parameLre de la meLhode. Cn LesLe l'egallLe des deux chaines grce a
la meLhode equals de la classe String eL non grce a l'operaLeur ==.
48
4.9.1. L'|nstruct|on cond|t|onne| |f
nous avons uLlllse l'lnsLrucLlon condlLlonnelle caracLerlsee par le moL cle if. Sa synLaxe esL :
if (condition)
instruction ;
uans ceLLe lnsLrucLlon, condition dolL Lre une expresslon a valeur booleenne (boolean). Sl la
valeur de condition esL true, alors l'lnsLrucLlon instruction sera execuLee, slnon !ava passe
a l'lnsLrucLlon sulvanLe.
luLL qu'une slmple lnsLrucLlon, ll esL posslble de meLLre un bloc d'lnsLrucLlons donL l'execuLlon sera
decldee par la condlLlon :
if (condition) {
instruction_1 ;
instruction_k ;
}
nous verrons de nombreux exemples plus Lard dans ce cours.
4.9.2. L'usage part|cu||er de |'|nstruct|on |f
nous avons vu la meLhode belongsTo :
public boolean belongsTo(String holder)
{
if (this.holder.equals(holder))
return true ;
return false ;
}
8emarquons que sl la condlLlon this.holder.belongsTo(holder) esL egale a true, nous
execuLons l'lnsLrucLlon return true qul renvole true. LL sl ceLLe condlLlon esL egale a false,
nous passons a l'lnsLrucLlon sulvanLe return false qul renvole false. AuLremenL dlL, ce qul esL
renvoye n'esL auLre que la valeur de this.holder.belongsTo(holder). LL ceLLe meLhode
belongsTo peuL Lre lnLelllgemmenL reecrlLe :
public boolean belongsTo(String holder)
{
return (this.holder.equals(holder)) ;
}
Ce genre de cas n'esL pas rare.
4.10. arcour|r |a tab|e des comptes
L'aLLrlbuL :
private ArrayList<BankAccount> accounstTable ;
esL declaree dans la classe Bank.
49
4.10.1. Les |ments d'une ArrayL|st
C'esL une llsLe donL la longueur, c'esL a dlre le nombre de compLes, esL obLenu par la meLhode
size() :
int accountsCount = accountsTable.size() ;
uans ceLLe llsLe, les elemenLs sonL lndexes enLre 0 eL accountsCount1. Sl l'on deslre obLenlr le
compLe lndlcee par i dans la llsLe :
BankAccount account = accountsTable.get(i) ;
4.10.2. L'|nstruct|on a|ternat|ve |f
Supposons que l'on veullle fabrlquer la llsLe de compLes credlLeurs eL la llsLe des compLes deblLeurs.
uans la classe BankAccount, nous allons creer une meLhode qul repondra true sl le compLe esL
deblLeur, false slnon. CeLLe meLhode uLlllse l'asLuce de la secLlon 4.9.2:
public boolean isDebitor()
{
return (amount < 0) ;
}
ulsque l'on deslre collecLer les compLes credlLeurs eL deblLeurs, nous allons creer deux
ArrayList de compLes :
ArrayList<BankAccount> debitAccountsTable
= new ArrayList<BankAccount>() ;
ArrayList<BankAccount> creditAccountsTable
= new ArrayList<BankAccount>() ;
Ces llsLes sonL lnlLlalemenL vldes.
our chacun des compLes de accountsTable, ldenLlfle par son lndex i dans la Lable, nous
execuLerons les lnsLrucLlons sulvanLes :
BankAccount account = accountsTable.get(i) ;
if (account.siDebitor()) {
debitAccountsTable.add(account) ;
} else {
creditAccountsTable.add(account) ;
}
Ces lnsLrucLlons vonL Lre repeLees pour i varlanL de 0 a accountsCount-1.
nous avons ecrlL une lnsLrucLlon alLernaLlve :
if (condition)
instructionSiVrai ;
else
instructionSiFaux ;
Les deux lnsLrucLlons peuvenL Lre des blocs d'lnsLrucLlons comme dans l'lnsLrucLlon condlLlonnelle.
CeLLe lnsLrucLlon evalue la condlLlon condition donL la valeur dolL Lre un booleen. Sl ce booleen
esL vral, elle execuLe instructionSiVrai, slnon elle execuLe instructionSiFaux.
30
4.10.3. L'|nstruct|on wh||e
our parcourlr la Lable des compLes, nous allons uLlllser l'lnsLrucLlon d'lLeraLlon while :
int i = 0 ; // initialization de i 0
while (i < accountsCount) { // tant que i < accountsCounts
BankAccount account = accountsTable.get(i) ;
if (account.siDebitor()) {
debitAccountsTable.add(account) ;
} else {
creditAccountsTable.add(account) ;
}
i = i + 1 ; // incrmenter i de 1
}
L'lnsLrucLlon while s'ecrlL :
while (condition)
instruction ;
L'lnsLrucLlon instruction peuL blen enLendu Lre remplace par un bloc d'lnsLrucLlons. LxecuLer
ceLLe lnsLrucLlon while revlenL a repeLer l'execuLlon de l'lnsLrucLlon instruction LanL que la
condition n'esL pas fausse.
La varlable i eLanL lnlLlallsee a 0, LanL que i < accountsCount, nous effecLuons les lnsLrucLlons
dans le bloc d'lnsLrucLlon du while (le corps du while). CeLLe sulLe d'lnsLrucLlon se Lermlne par
l'lncremenLaLlon de i : i = i + 1. i va donc parLlr de zero eL a chaque execuLlon du corps du
whlle, ll sera lncremenLer de 1 [usqu'a ce que i solL egal a accountsCount.
Les lnsLrucLlons du corps de la boucle while seronL donc execuLees pour i var|ant de
0 accountsCount-1.
4.10.4. L'|nstruct|on d'|trat|on for
une consLrucLlon programmaLlque Lelle que :
int i = 0 ;
while (i < count) {
instructions
i = i + 1 ;
}
esL couranLe en lnformaLlque. Llle revlenL a execuLer les lnsLrucLlons instructions pour i
varlanL de 0 [usqu'a count-1.
1ous les langages de programmaLlon, ou presque, proposenL une lnsLrucLlon d'lLeraLlon nommee
for qul esL plus compacLe mals sLrlcLemenL equlvalenLe aux lnsLrucLlons cl-dessus :
31
L'lnsLrucLlon :
int i = 0 ; // initialization de i 0
while (i < accountsCount) { // tant que i < accountsCounts
BankAccount account = accountsTable.get(i) ;
if (account.siDebitor()) {
debitAccountsTable.add(account) ;
} else {
creditAccountsTable.add(account) ;
}
i = i + 1 ; // incrmenter i de 1
}
esL equlvalenLe a l'lnsLrucLlon for :
for (int i = 0 ; i < accountsCount ; i = i + 1) {
BankAccount account = accountsTable.get(i) ;
if (account.siDebitor()) {
debitAccountsTable.add(account) ;
} else {
creditAccountsTable.add(account) ;
}
}
La forme generale de l'lnsLrucLlon for esL :
for ( init ; condition ; nextStep )
instruction
ou condition esL une expresslon a valeur booleenne, init, nextStep eL instruction sonL
des lnsLrucLlons. L'lnsLrucLlon instruction peuL Lre remplacee par un bloc d'lnsLrucLlons. Llle
esL equlvalenLe a l'lnsLrucLlon while sulvanLe :
init ;
while (condition) {
instruction ;
nextStep ;
}
L'lnsLrucLlon for esL souvenL uLlllsee pour qu'une varlable de Lype int parcoure un lnLervalle de
valeur, comme cecl :
int i ;
for (i = 0 ; i < accountsCount ; iu = i + 1)
System.out.println(accounstTabmle.get(i).getHolder()) ;
32
uans ce cas, ll esL posslble de declarer la varlable i dans la boucle for. Sa porLee sera alors la boucle
for unlquemenL :
for (int i = 0 ; i < accountsCount ; iu = i + 1)
System.out.println(accounstTabmle.get(i).getHolder()) ;
4.10.S. Les |trateurs
un |trateur esL un ob[eL gnr|que parLlculler qul permeL de parcour|r une sLrucLure de
donnees.
1ouLes les sLrucLures de donnees proposees par !ava onL une meLhode qul permeL de generer un
lLeraLeur permeLLanL de parcourlr la sLrucLure. Ln parLlculler, la classe ArrayList<T> a une
meLhode de slgnaLure :
public Iterator<T> iterator() ;
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 ArrayList. Cherchez la documenLaLlon d'ArrayList eL
Lrouvez la descrlpLlon de la meLhode iterator. 8egardez la classe Iterator.
L'ob[eL de la classe Iterator<T> permeL de parcourlr la sLrucLure de donnees en accedanL
successlvemenL a chacun des elemenLs de Lype T qu'elle conLlenL. Cela se falL de manlere
LransparenLe a l'alde de deux meLhodes :
boolean hasNext() ;
CeLLe meLhode reLourne true s'll y a encore des elemenLs a parcourlr, false slnon.
T next() ;
CeLLe meLhode reLourne l'elemenL sulvanL de la sLrucLure de donnees.
nous pouvons donc parcourlr une sLrucLure ArrayList en oubllanL l'lndexaLlon numerlque des
ob[eLs qu'elle conLlenL. Sl l'on declde de parcourlr la llsLe des BankAccount avec un lLeraLeur pour
consLrulre la llsLe des compLes deblLeurs eL credlLeurs sans uLlllser de boucle while base sur les
lndlces (4.10.3) nl de boucle for (4.10.4) :
Iterator<BankAccount> iterator = accountsTable.iterator() ;
while (iter.hasNext()) {
BankAccount account = iter.next() ;
if (account.isDebitor()) {
debitAccountsTable.add(account) ;
} else {
creditAccountTable.add(account) ;
}
}
33
4.11. L'a|gor|thme d'Luc||de
un a|gor|thme esL une sulLe d'operaLlons qu'un auLomaLe peuL execuLer pour reallser un
calcul.
vous Lrouverez mllle deflnlLlons du moL a|gor|thme dans la llLLeraLure eL sur le Web. Lucllde a
lnvenLe un algorlLhme permeLLanL de calculer le CCu de deux enLlers sLrlcLemenL poslLlfs. our
calculer le CCu de deux enLlers u eL v sLrlcLemenL poslLlfs Lels que u > v :
1. lnlLlallser une varlable A avec la valeur u.
2. lnlLlallser une varlable 8 avec la valeur v.
3. Calculer k = A 8, resLe de la dlvlslon de A par 8.
4. lalre A = 8.
3. lalre 8 = k.
6. Sl k = 0, reLourner en 3.
7. Le CCu de u eL v esL la valeur de A.
4.11.1. La formu|at|on ob[et
Ln programmaLlon orlenLe ob[eL, ll n'y a pas de slmple foncLlon mals unlquemenL des meLhodes. Cn
peuL par exemple lmaglner une classe Mathematician donL les meLhodes sonL des algorlLhmes
celebres. Cn auralL alors :
public class Mathematician
{
/** Computes the gcd of two positives numbers
* using Euclids algorithm.
*/
public int gcd(int u, int v)
{
}
}
our calculer le CCu des nombres 21 eL 23, on commencera par creer l'ob[eL Mathematician :
Mathematician mathematician = new Mathematician() ;
uls on uLlllse ceL ob[eL pour acceder a l'algorlLhme gcd :
int result = mathematician.gcd(21,25) ;
L'ob[eL Mathematician peuL Lre uLlllse pour d'auLres calculs.
34
4.11.2. La bouc|e do-wh||e
La sulLe d'lnsLrucLlons :
1. Calculer k = A 8, resLe de la dlvlslon de A par 8.
2. lalre A = 8.
3. lalre 8 = k.
4. Sl k = 0, reLourner en 1.
exLralLe de l'algorlLhme d'Luclld, conLlenL l'lnsLrucLlon reLourner en 3 qul n'exlsLe pas en !ava. Cn
dlsLlngue neanmolns une boucle 1-2-3-4, l'lnsLrucLlon 4 provoquanL le reLour en 1. our programmer
cela en !ava, on uLlllsera l'lnsLrucLlon do-while qul s'ecrlL :
do {
instructions ;
} while (condition) ;
Son execuLlon repeLe les lnsLrucLlons instructions [usqu'a ce que la condlLlon devlenne fausse.
uans noLre cas, la boucle d'lnsLrucLlons 1-2-3-4 peuL Lre remplacee par :
do {
R = A % B ;
A = B ;
B = R ;
} while(R != 0) ;
4.11.3. La mthode gcd
A presenL, nous pouvons ecrlre la meLhode gcd de la classe Mathematician :
public int gcd(int u, int v)
{
int a, b, r ;
if (u > v) { // ordering u and v
a = u ;
b = v ;
} else {
a = v ;
b = u ;
}
do { // computing gcd
r = a % b ;
a = b ;
b = r ;
} while (r != 0) ;
return a ; // gcd is a
}
33
4.12. D'autres |nstruct|ons d'affectat|on
volcl d'auLres synLaxes pour l'lnsLrucLlon d'affecLaLlon. Llles sonL appllcables aux Lypes scalalres :
a += b ; equlvalenLe a a = a + b ;
a -= b ; equlvalenLe a a = a - b ;
a *= b ; equlvalenLe a a = a * b ;,
a /= b ; equlvalenLe a a = a / b ;,
a %= b ; equlvalenLe a a = a % b ;,
a++ ; equlvalenLe a a += 1 ; equlvalenLe a a = a + 1 ;
a-- ; equlvalenLe a a -= 1 ; equlvalenLe a a = a - 1 ;
4.13. L'|nstruct|on sw|tch de tra|tement par cas
un tra|tement par cas esL un LralLemenL qul depend de la valeur d'un Lype sca|a|re.
ll esL posslble de programmer un LralLemenL par cas en !ava a l'alde de l'lnsLrucLlon switch. uans
ceLLe lnsLrucLlon, on consldere une expresslon de Lype sca|a|re. ne sonL pas concernes les ob[eLs eL
les nombres floLLanLs de Lype float eL double. L'lnsLrucLlon switch permeL d'execuLer des
lnsLrucLlons dlfferenLes selon la valeur de l'expresslon. L'lnsLrucLlon switch permeL d'evlLer de
programmer des LesLs d'egallLe en serle.
Lxemp|e. uans ceL exemple, on declde de desslner une flgure en foncLlon du nombre de ses cLes
qul esL suppose Lre dans un aLLrlbuL. Cn dlsLlngue les cas 1, 2 eL les auLres valeurs.
public void drawFigure()
{
switch (sideCount)
{
case 1 :
drawPoint() ;
break ;
case 2 :
drawLine() ;
break ;
default :
drawPolygone() ;
break ;
}
)
L'lnsLrucLlon swicth commence par switch (sideCount). uls enLre les accolades, ll y a des
bloc de cholx. un bloc qul commence par case sulvle d'une valeur eL d'un deux-polnLs correspond
au cas ou sideCount esL egale a ceLLe valeur. Le bloc se Lermlne par l'lnsLrucLlon break. Le cas
default correspond, s'll esL presenL, au cas ou sideCount n'esL egale a aucune valeur des blocs
case. Le bloc se Lermlne egalemenL par une lnsLrucLlon break. Sl la cas default n'esL pas llsLe eL
que la valeur de sideCount n'esL egale a aucune des valeurs des blocs case, l'lnsLrucLlon ne falL
rlen. ALLenLlon a ne pas oubller l'lnsLrucLlon break en fln des blocs ! Ln effeL, sl elle n'esL pas
presenLe eL que le bloc esL execuLe, son execuLlon sera conLlnuer avec le bloc sulvanL.
36
4.14. Une bouc|e for part|cu||re
nous avons vu la classe ArrayList qul esL une sLrucLure de donnees parLlcullere. nous avons vu
commenL parcourlr les elemenLs conLenus dans ce Lype de sLrucLure de donnees a l'alde d'un lndex
car les elemenLs d'une ArrayList sonL numeroLes. nous avons vu commenL parcourlr les
elemenLs de la sLrucLure en uLlllsanL un ob[eL de la classe Iterator fournl par la sLrucLure de
donnees. uepuls la verslon 6 de !ava, ll esL posslble de parcourlr les sLrucLures de donnees de !ava
grce a une boucle parLlcullere :
ArrayList<BankAccount> accountsList = ;
for (BankAccount account : accountsList) {
System.out.println(account.getHolder() ;
}
La varlable account va prendre successlvemenL pour valeurs Lous les elemenLs de la sLrucLure
accountsList. CeLLe synLaxe esL equlvalenLe a l'uLlllsaLlon d'un lLeraLeur. Llle esL uLllslable avec
LouLes les sLrucLures de donnees proposees par !ava.
4.1S. Conc|us|ons
ll exlsLe de nombreuses varlaLlons dans l'execuLlon des lnsLrucLlons de !ava. vous les decouvrlrez
lorsque ce sera necessalre. Ln aLLendanL, ll esL preferable de programmer avec les lnsLrucLlons Lelles
qu'elles sonL decrlLes dans ce chaplLre.
37
S. C|asses et ob[ets
Les ob[ets sonL des enLlLes lnformaLlques qul communlquenL par envols de messages. Les ob[eLs
conLlennenL des valeurs appelees attr|buts. arml les aLLrlbuLs, on peuL Lrouver des rfrences sur
d'auLres ob[eLs. une reference sur un ob[eL permeL de lul envoyer un message. our chaque Lype de
message que l'ob[eL peuL recevolr, l'ob[eL connaiL une mthode assoclee au Lype de message. CeLLe
meLhode esL une procedure lmperaLlve qul esL excute par |'ob[et lorsqu'll reolL le Lype de
message assocle.
un Lype d'ob[eL esL decrlL par une c|asse. La classe ecrlL les aLLrlbuLs : nom eL Lype de valeur. La
classe decrlL les meLhodes uLlllsees pour repondre aux messages. Le programmeur peuL creer des
ob[eLs a parLlr de la classe. C'esL le processus d'|nstanc|at|on. Cn dlL que les ob[eLs sonL des |nstances
de la classe ou que les ob[eLs apparLlennenL a la classe.
Cn pourralL dlre qu'un ob[eL conLlenL les donnees qul le caracLerlsenL eL qu'll connaiL des meLhodes
qul deflnlssenL ce donL ll esL capable.
Cn pourralL egalemenL dlre qu'un ob[eL a une |nterface consLlLuee des operaLlons qu'on peuL lul
demander eL une parLle lnLerne eL proLegee composees des donnees qu'll conLlenL eL des meLhodes
donL ll se reserve l'usage.
S.1. D|chotom|e c|asse-ob[ets
Les dlfferenLes enLlLes peuvenL Lre placees comme sulL :
La classe deLlenL les declaraLlons d'aLLrlbuLs, les declaraLlons eL les mlses en ouvre des
meLhodes.
Les ob[eLs parLagenL les declaraLlons d'aLLrlbuLs, les declaraLlons eL les mlses en ouvre des
meLhodes a Lravers leur classe commune.
Chaque ob[eL, lnsLance de la classe, possede ses propres valeurs d'aLLrlbuLs.
ues lnformaLlons, lnvlslbles pour le programmeur !ava, sonL sLockees dans l'ob[eL pour
lndlquer sa classe d'lnsLanclaLlon.
Cela peuL se resumer par le dessln :
38
S.2. Var|ab|es de c|asse
Cn remarque que chaque ob[eL a ses propres valeurs d'aLLrlbuLs. uonc, les ob[eLs d'une mme classe
n'onL aucun llen enLre eux, aucune valeur parLagee, sl ce n'esL la classe. 1ouL ce qul esL dans la classe,
les meLhodes par exemple, esL parLage par Lous les ob[eLs de la classe. ll peuL arrlver qu'll solL
preferable que les ob[eLs, lnsLances d'une mme classe, alenL besoln d'une valeur parLagee.
Lxemp|e. uans noLre programme de banque, on deslre malnLenlr le solde LoLal de la banque. Chaque
depL ou reLralL d'un compLe en banque dolL modlfler une varlable conLenanL le solde de la banque
en plus de modlfler l'aLLrlbuL conLenanL le solde du compLe. CeLLe varlable peuL Lre un aLLrlbuL de la
classe Bank. C'esL la soluLlon la plus loglque. Mals alors chaque ob[eL de la classe BankAccount
devra avolr une reference sur l'ob[eL banque. Cela peuL se falre assez facllemenL. Mals ll exlsLe une
auLre soluLlon : une var|ab|e de c|asse de nom bankBalance eL que nous allons declare dans la
classe BankAccount :
public class BankAccount
{
private static double bankBalance = 0.0 ;
public double withdraw(double value)
{
amount -= value ;
bankBalance -= value ;
return amount ;
}
public double deposit(double value)
{
amount += value ;
bankBalance += value ;
return account ;
}
}
39
L'aLLrlbuL bankBalance esL declare avec le moL cle static. C'esL ce moL cle qul en falL une
varlable de classe.
La valeur d'une var|ab|e de c|asse esL deLenue par la classe eL non par l'ob[eL. Llle esL
donc parLagee par Lous les ob[eLs de la classe.
Cela peuL se represenLer alnsl :
Cn dlsLlnguera donc malnLenanL :
l'attr|but, aussl appele var|ab|e d'|nstance pour lequel chaque ob[eL possede sa
propre valeur ,
les var|ab|es de c|asse donL la valeur esL deLenue dans la classe.
noLons que les varlables de classe sonL Lres peu uLlllsees.
S.2.1. Imp|menter des constantes par des var|ab|es de c|asses
Cn peuL uLlllser les varlables de classe pour deflnlr des consLanLes. une consLanLe esL une donnee
ldenLlflee par un symbole donL la valeur ne changera pas LouL le long de l'execuLlon du programme.
our lnLerdlre a une varlable de classe ou un aLLrlbuLs ou une varlable locale de
changer de valeur duranL l'execuLlon du programmer, on uLlllse le moL cle final.
our deflnlr une consLanLe, on uLlllsera donc le moL cle final car elle ne dolL pas changer de valeur
apres sa creaLlon eL le moL cle static car on veuL qu'elle solL deLenue par une classe.
Lxemp|e. Creons la classe Mathematician avec une consLanLe de nom PI.
public class Mathematician
{
public static final double PI = 3.14 ;
}
60
Cn peuL alors uLlllser la consLanLe PI avec la noLaLlon Mathematician.PI car PI esL une
varlable de classe (moL cle static).
C'esL l'un des rares cas ou l'on ne respecLe pas le prlnclpe d'encapsulaLlon. Ln effeL, PI
esL declaree flnal eL ll n'y a aucune chance qu'll pulsse Lre changer duranL l'execuLlon
du programme.
noLons que l'lnlLlallsaLlon avec la valeur 3.14 esL falLe au momenL de la declaraLlon.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Math. Cherchez la documenLaLlon de Math eL examlnez-la.
S.2.2. Imp|menter une mmo|re g|oba|e avec des var|ab|es de c|asses
ll esL parfols dlfflclle d'eLabllr des llens enLre les ob[eLs d'un programme. Cn peuL alors fabrlquer ce
que l'on appelle une memolre globale.
une mmo|re g|oba|e esL un ensemble de varlables accesslbles a Lous les ob[eLs du
programme.
Les varlables de la memolre globale seronL des varlables de classe.
Lxemp|e. uans noLre programme de gesLlon de banque, on lmplemenLe une classe
BankGlobalMemory qul sera la memolre globale. Llle conLlendra des llsLes.
public class BankGlobalMemory
{
public static ArrayList<BankAccount> accountsTable ;
}
Alnsl la Lable des compLes en banque esL accesslble dans LouLe l'appllcaLlon grce a la noLaLlon :
BankGlobalMemory.accounstTable
une varlable de classe comme accountsTable ne respecLe pas le prlnclpe
d'encapsulaLlon eL on peuL le deplorer. nous verrons plus loln, avec les meLhodes de
classe, commenL respecLer le prlnclpe d'encapsulaLlon.
Cn evlLera, auLanL que falre se peuL, ceLLe approche car elle LradulL en general un
manque de reflexlon ou blen . de la paresse !
61
S.2.3. In|t|a||sat|on des var|ab|es de c|asses
Cn peuL souvenL lnlLlallser les varlables de classes lors de leurs declaraLlons. Ln parLlculler, sl la
valeur d'lnlLlallsaLlon esL une valeur ou sl elle peuL se calculer a l'alde d'une slmple expresslon :
public class Mathematician
{
public static final double PI = 3.14 ;
}
Mals parfols l'lnlLlallsaLlon d'une varlable de classe requlerL une sulLe d'lnsLrucLlons. Cn lnLrodulL
alors dans la classe un bloc static.
Lxemp|e. lnlLlallsons une varlable de classe accountsType qul conLlenL les Lypes de compLe :
public class BankGlobalMemory
{
public static final ArrayList<String> accountsType ;
static {
accountsType = new ArrayList<String>() ;
accounstType.add("checking") ;
accounstType.add("saving") ;
accounstType.add("money market") ;
accounstType.add("student") ;
}
}
ll peuL y avolr plusleurs blocs static dans une classe. lls seronL execuLes dans l'ordre de leur
apparlLlon dans la classe.
S.3. ketour sur |e mot c| f|na|
Le moL cle final uLlllse lors de la declaraLlon d'une var|ab|e d'|nstance (aLLrlbuL) ou
d'une var|ab|e de c|asse slgnlfle que la varlable ne pourra plus Lre modlflee apres son
lnlLlallsaLlon.
L'lnlLlallsaLlon d'une varlable de classe peuL se falre solL au momenL de la declaraLlon (comme
l'lnlLlallsaLlon de PI en 3.2.3) ou grce a un bloc static (comme l'lnlLlallsaLlon de
accountsType en 3.2.3).
L'lnlLlallsaLlon d'une varlable d'lnsLance peuL se falre au momenL de la declaraLlon :
public class Point
{
private int x = 0 ;
private int y = 0 ;
}
62
L'lnlLlallsaLlon d'une varlable d'lnsLance peuL egalemenL se falre dans le consLrucLeur comme nous
l'avons de[a vu.
une varlable declaree final peuL evenLuellemenL Lre lalssee en acces public mals ll fauL falre
aLLenLlon aux sLrucLures de donnees. Mme sl une sLrucLure de donnees esL declare final, rlen
n'empche de modlfler le conLenu de la sLrucLure de donnees. ll fauL donc, dans ce cas, appllquer le
prlnclpe d'encapsulaLlon des donnees eL declarer l'aLLrlbuL private.
L'uLlllsaLlon du moL cle final permeL au compllaLeur de reallser des opLlmlsaLlons qul
rendenL le programme plus efflcaces.
S.4. ketour sur |es mthodes
une meLhode esL excute par un ob[et lorsqu'll reolL le message correspondanL. uans une
meLhode, l'ob[eL qul l'execuLe esL accesslble avec la reference this.
une meLhode esL declaree dans une classe. Llle se compose de |'en-tte eL du corps de la meLhode.
Le corps esL un bloc d'lnsLrucLlons :
public int getX() // en-tte
{ // corps : accolade ouvrante
return x ; // corps : instruction (s)
} // corps : accolade fermante
L 'en-LLe de la meLhode peuL comporLer dlvers moL cles :
La dc|arat|on de v|s|b|||t esL composee de l'un des moLs sulvanLs :
public : n'lmporLe quel auLre ob[eL peuL demander a ceL ob[eL d'execuLer ceLLe meLhode ,
private : seul l'ob[eL lul-mme peuL declder d'execuLer ceLLe meLhode ,
protected : sera vu plus Lard car lle aux noLlons d'herlLage eL de pockoqes.
une meLhode declaree avec le moL cle static esL une meLhode de classe.
63
S.S. Les mthodes de c|asse
une meLhode de classe esL une meLhode declaree avec le moL cle static.
une meLhode de classe esL execuLee par la classe, pas par l'ob[eL.
Ln consequence, une meLhode de classe n'a acces qu'aux varlables de classes deLenues par la classe
eL non aux varlables d'lnsLances (les aLLrlbuLs) deLenues par les ob[eLs. Ln effeL, ll n'y a pas d'ob[eL
qul execuLe une meLhode de classe.
Lxemp|e. La varlable bankBalance que nous avlons uLlllsee pour malnLenlr le solde global de la
banque auralL pu Lre declaree dans la classe Bank :
public class Bank
{
private static double bankBalance = 0.0 ;
public static void updateBalance(double amount)
{
bankBalance += amount ;
}
}
uls dans la classe BankAccount, la meLhode de classe updateBalance sera uLlllsee alnsl :
public class BankAccount
{
public double withdraw(double value)
{
amount -= value ;
Bank.updateBalance(-1 * value) ;
return amount ;
}
public double deposit(double value)
{
amount += value ;
Bank.updateBalance(value) ;
return amount ;
}
}
Cn volL que la meLhode de classe updateBalance de la classe Bank, s'uLlllse avec l'expresslon
Bank.updateBalance() eL n'a pas besoln d'ob[eL pour s'execuLer. La classe lul sufflL. noLons
blen, encore une fols, que ce n'esL pas l'ob[eL qul execuLe la meLhode de classe mals la classe.
64
S.6. Le type de |a rponse
un ob[eL execuLe une meLhode en reponse a un envol de message de la parL d'un auLre ob[eL. Le
programmeur peuL cholslr que l'ob[eL qul execuLe la meLhode reponde expllclLemenL ou pas. Sl
l'ob[eL ne repond pas expllclLemenL, le Lype de la reponse sera void.
Lxemp|e. Sl un ob[eL graphlque de la classe Point reolL un message setCoords(12,34) qul lul
demandenL de changer ses coordonnees, ll execuLe la meLhode correspondanLe qul n'a pas besoln
de repondre. uonc :
public class Point
{
private int x ;
private int y ;
public void setCoords(int x, int y)
{
this.x = x ;
this.y = y ;
}
}
Cuand une meLhode ne repond rlen, ll esL neanmolns posslble de meLLre fln a l'execuLlon de la
meLhode avec une lnsLrucLlon return sans parameLre.
Lxemp|e. Supposons que dans la meLhode setCoords() de la classe Point, on dolve redesslner
le polnL. Alors, ll peuL Lre lnLeressanL de verlfler que les nouvelles coordonnees sonL dlfferenLes des
anclennes, slnon ll ne fauL pas effecLuer de changemenLs de coordonnees.
public class Point
{
private int x ;
private int y ;
public void setCoords(int x, int y)
{
if (this.x == x && this.y == y)
return ;
this.x = x ;
this.y = y ;
redraw() ;
}
}
63
ALLenLlon ! Mme sl une meLhode ne renvole rlen, l'ob[eL appelanL dolL neanmolns
aLLendre la fln de l'execuLlon de la meLhode avanL de reprendre son execuLlon.
Sl la meLhode d'un ob[eL dolL repondre, ce sera avec des valeurs d'un Lype donne. Le Lype de la
reponse peuL Lre un Lype scalalre (int, double, char, eLc.) ou un Lype reference.
Lxemple.
public class Point
{
private int x ;
private int y ;
public double distanceToOrigin()
{
return Math.sqrt(x*x + y*y) ;
}
}
uans une lnsLrucLlon return expr, expr dolL Lre une expresslon donL la valeur a le Lype declare
de la reponse, lcl double. CeLLe valeur esL la reponse de la meLhode. L'execuLlon d'une lnsLrucLlon
return expr meL fln a l'execuLlon de la meLhode. ll peuL y avolr plusleurs occurrences de
l'lnsLrucLlon return dans une meLhode.
S.7. Lxcut|on d'une mthode
Cuand un ob[eL sender envole un message a un ob[eL receiver, l'ob[eL receiver execuLe la
meLhode correspondanLe. uuranL l'execuLlon de la meLhode par l'ob[eL receiver, l'ob[eL sender
se meL en aLLenLe [usqu'a ce que l'execuLlon se Lermlne.
Cn dlL que l'envol de message esL synchrone.
S.8. Noms des mthodes, des attr|buts et des var|ab|es
Le nom d'une meLhode peuL Lre n'lmporLe quel symbole blen forme. Cn cholslL normalemenL une
perlphrase decrlvanL ce que falL ou calcule la meLhode puls le nom s'obLlenL en supprlmanL les
espaces eL en caplLallsanL la premlere leLLre de chaque moL a l'excepLlon du premler moL.
Lxemp|e. La perlphrase move flgure Lo devlendra moveFigureTo.
Ln !ava, on falL de mme pour les noms d'aLLrlbuL eL les noms de de varlables.
S.9. aramtres des mthodes
Les declaraLlons de parameLres sonL llsLees enLre des parenLheses derrlere le nom de la meLhode.
Llles sonL separees par des vlrgules. Chaque declaraLlon de parameLre esL consLlLuee du Lype eL du
nom du parameLre. Le Lype peuL Lre un Lype scalalre ou un Lype reference. Les noms des
parameLres sonL normalemenL cholsls comme on cholslL les noms de meLhodes (cf. 3.8).
66
S.10. Appe| par va|eur
Les parameLres Lels que nommes lors de la declaraLlon de la meLhode sonL appeles des
paramtres forme|s.
Lxemp|e. uans une meLhode declaree alnsl :
public void setXY(int x, int y)
{
this.x = x ;
this.y = y ;
}
les parameLres formels sonL x eL y.
Les parameLres uLlllses lors de l'envol de message sonL appeles paramtres effect|fs,
parfols parameLres acLuels mals c'esL un angllclsme.
Lxemp|e. uans les lnsLrucLlons :
int v = 3 ;
g.setXY(12+1,v) ;
les parameLres effecLlfs sonL 12+1 eL v.
Le mecanlsme qul lle les parameLres effecLlfs aux parameLres formels en !ava esL appele
appe| par va|eur.
Cela slgnlfle que les parameLres effecLlfs sonL evalues avanL l'execuLlon de la meLhode eL les
parameLres formels prennenL la va|eur des parameLres effecLlfs au debuL de l'execuLlon de la
meLhode.
Lxemp|e. uans les lnsLrucLlons :
int v = 3 ;
g.setXY(12+1,v) ;
la parameLre formel x de setXY(int x, int y) prend la valeur 13 eL y prendra la valeur 3.
noLons blen que y esL lle a la valeur de v eL non a la varlable v. une modlflcaLlon du
parameLre formel y pendanL l'execuLlon de la meLhode n'aura aucun lmpacL sur v.
La valeur d'une reference esL la reference elle-mme. Lorsque le parameLre effecLlf esL une
reference sur un ob[eL, le parameLre formel prend comme valeur une reference sur le mme ob[eL.
1ransmeLLre une reference sur un ob[eL a une meLhode, c'esL permeLLre a la meLhode qul la reolL
d'acceder a l'ob[eL a Lravers les meLhodes publlquemenL accesslbles de l'ob[eL.
67
Lxemp|e. Conslderons le programme sulvanL :
LxecuLons-le pas a pas en desslnanL les varlables :
1)
2)
3)
68
4)
3)
S.11. Surcharge de mthodes
Lorsqu'un ob[eL reolL un message m(a1,..,ak), ll repond avec une meLhode de nom m ayanL k
parameLres formels donL les Lypes correspondenL aux Lypes de a1,,ak. ll esL posslble de declarer
des meLhodes ayanL le mme nom mals des parameLres dlfferenLs solL en nombre solL en Lypes. Cecl
s'appelle la surcharge de mthodes.
Lxemp|e. volcl une classe EURAmount charge de modellser une somme en Luros.
public class EURAmount
{
private double amount ;
public EURAmount(double amount)
{
this.amount = amount ;
}
public double getAmount()
{
return amount ;
}
}
69
ue la mme manlere, volcl une classe USDAmount charge de modellser une somme en uollar uS.
uans ceLLe classe, nous allons lmplemenLer une meLhode convertToEUR() qul converLlra la
somme en uollar uS en une somme en Luros.
public class USDAmount
{
private double amount ;
public USDAmount(double amount)
{
this.amount = amount ;
}
public double getAmount()
{
return amount ;
}
public EURAmount convertToEur()
{
double rate = Bank.getExchangeRate("EUR","USD") ;
return new EURAmount(amount * rate) ;
}
}
nous avons uLlllse une meLhode de classe getExchangeRate de la classe Bank qul permeL de
connaiLre le Laux de change de deux monnales. nous pouvons declarer la classe des compLes en
Luros comme sulL :
public class EURAccount
{
private double balance ;
public void deposit(EURAmount amount)
{
balance += amount.getAmount() ;
}
public void deposit(USDAmount amount)
{
deposit(amount.convertToEUR()) ;
}
}
nous avons la un exemple de surcharge de meLhode. La meLhode deposit peuL Lre uLlllse avec
des parameLres de Lypes dlfferenLs.
S.12. Surcharge de constructeurs
Comme nous l'avons enLrevu, ll esL aussl posslble de surcharger les consLrucLeurs.
Lxemp|e. La classe Point avec deux consLrucLeurs.
70
public class Point
{
private int x ;
private int y ;
public Point(int x, int y)
{
this.x = x ;
this.y = y ;
}
public Point(double rho, double theta)
{
this.x = (int)(rho * Math.cos(theta)) ;
this.y = (int)(rho * Math.sin(theta)) ;
}
}
ll esL posslble pour un consLrucLeur d'appeler un auLre consLrucLeur. Cela se falL avec le
moL cle this. Attent|on : cet appe| do|t tre |a prem|re |nstruct|on.
Lxemp|e. Cn reprend la classe Point.
public class Point
{
private int x ;
private int y ;
public Point(int x, int y)
{
this.x = x ;
this.y = y ;
}
public Point(double rho, double theta)
{
this((int)(rho * Math.cos(theta)),
(int)(rho * Math.sin(theta))) ;
}
}
S.13. Le |ancement d'un programme
Au lancemenL d'un programme !ava, on cree des ob[eLs puls on envole un message a l'un de ceux-cl.
Comme l'on ne dlspose lnlLlalemenL d'aucun ob[eL, l'operaLlon de lancemenL du programme esL
effecLuee par une mthode de c|asse donL la slgnaLure esL :
public static void main(String[] args)
71
CeLLe meLhode dolL Lre declaree dans une classe quelconque. Llle ne necesslLe pas d'ob[eL pour Lre
execuLee, c'esL la classe qul l'execuLe. Lorsque l'on deslre execuLer ce programme, on demande a
!ava d'execuLer au demarrage la classe qul conLlenL la meLhode main.
uans la meLhode
public static void main(String[] args)
args esL un Lableau de chaines de caracLeres qul conLlenL les argumenLs exLernes donnes au
programme. C'esL l'un des Lres rares cas ou !ava nous lmpose des Lableaux.
Lxemp|e. Supposons un programme de slmulaLlon de roboLs qul prend en argumenLs exLernes les
noms des roboLs.
import java.util.* ;
public class Robots Simulation
{
public static void main(String[] args)
{
ArrayList<Robot> robots = new ArrayList<Robot>() ;
int count = args.length ;
for (int i = 0 ; i < count ; i++)
robots.add(new Robot(args[i])) ;
}
}
S.14. Les packages
un package !ava (paqueLage en franals) esL une collecLlon loglque de classe. uans un programme
!ava, les classes sonL regroupees en packages.
Lxemp|e :
un package pour les classes reallsanL les enLrees-sorLles.
un package pour les classes reallsanL des communlcaLlons reseaux.
un package pour els classes reallsanL l'lnLerface graphlque.
Les noms des packages sonL des symboles ecrlLs en leLLres mlnuscules.
L'envlronnemenL de developpemenL Lcllpse vous permeL de creer des packages.
un package esL slmplemenL maLerlallse par un reperLolre conLenanL les flchlers .java de
declaraLlon des classes du package.
Les classes de bases du langage !ava sonL organlsees en packages.
72
Lxemp|e :
uans une appllcaLlon, on organlsera ses classes en packages.
Lxemp|e :
La package main conLenanL la classe de lancemenL Main.java.
Le package interface conLenanL les classes de l'lnLerface graphlque.
Le package interface.utils conLenanL des classes uLlllLalres pour l'lnLerface graphlque.
Le package engine conLenanL le moLeur de l'appllcaLlon.
Cn remarquera la noLaLlon avec des polnLs dans interface.utils.
une appllcaLlon esL composee de packages hlerarchlses comme les reperLolres d'un sysLeme de
flchlers. Le flchler de declaraLlon d'une classe dans un packages, par exemple le package
interface.utils, dolL commencer par la declaraLlon :
package interface.utils ;
Sl la classe a besoln de connaiLre des classes d'auLres packages, ll fauL une declaraLlon d'lmporLaLlon
comme :
import java.util.* ; // pour la classe ArrayList
import engine.* ; // pour les classes du package engine
une erreur dans la declaraLlon package peuL ne pas Lre deLecLee a la compllaLlon
mals se manlfesLer a l'execuLlon.
73
6. Interfaces de programmat|on
6.1. La not|on d'|nterface
Cn appelle |nterface d'un ob[et l'ensemble des meLhodes de l'ob[eL qul sonL accesslbles depuls
l'exLerleur de l'ob[eL. our lnLeraglr avec l'ob[eL, ll fauL avolr une rfrence sur l'ob[eL eL connaiLre
son |nterface. ConnaiLre l'lnLerface d'un ob[eL, c'esL connaiLre les s|gnatures de ses mthodes eL,
blen sr, la documenLaLlon assoclee. Ln !ava, ll esL posslble de maLerlallser l'lnLerface d'un ob[eL en
permeLLanL des dc|arat|ons d'|nterface.
ALLenLlon ! ll ne fauL pas confondre les |nterfaces de programmat|on, ob[eL de ce
cours, avec les |nterfaces graph|ques (InM) qul seronL vue plus loln.
6.2. Dc|arat|on d'|nterface
une declaraLlon d'lnLerface porLe un nom eL ressemble a une declaraLlon de classe mals on n'y
Lrouve que les slgnaLures des meLhodes.
Lxemp|e :
public interface BankAccountInterface
{
public void withdraw(double amount) ;
public void deposit(double amount) ;
public double getBalance() ;
}
6.3. Imp|menter une |nterface
une lnLerface n'esL pas une classe.
74
une classe peuL declarer meLLre en ouvre ou lmplemenLer une ou plusleurs lnLerfaces. une
lnLerface peuL Lre vue comme un engagemenL a meLLre en ouvre les meLhodes llsLees dans
l'lnLerface. L'lnLerface ne dlL rlen de la mlse en ouvre des meLhodes llsLees.
Lxemp|e. lmplemenLons l'lnLerface BankAccountInterface dans une classe BankAccount.
public class BankAccount
implements BankAccountInterface
{
private double balance ;
public void withdraw(double amount)
{
balance -= amount ;
}
public void deposit(double amount)
{
balance += amount ;
}
public double getBalance()
{
return balance ;
}
}
Sl une classe declare qu'elle lmplemenLe une lnLerface, elle dolL proposer une lmplemenLaLlon des
meLhodes llsLees dans l'lnLerface. La classe peuL blen sr proposer des meLhodes qul ne sonL pas
llsLees dans l'lnLerface.
6.4. L'|nterface, out|| de concept|on
Les lnLerfaces de !ava sonL un ouLll de concepLlon.
Les lnLerfaces dolvenL Lre uLlllsees lors de la phase de concepLlon du loglclel. Lors de ceLLe phase, on
ldenLlfle les dlfferenLs Lypes d'ob[eLs parLlclpanL au probleme. Chaque ob[eL esL alors caracLerlse par
son lnLerface documenLe. Sl elle esL blen commenLee, l'lnLerface apparaiL comme une spc|f|cat|on
des meLhodes que les ob[eLs dolvenL lmplemenLer.
Cn pense |'|nterface avanL de penser la c|asse.
6.4.1. Lxemp|e : |'|nterface 8|nary1reeInterface
renons l'exemple d'un arbre blnalre. un arbre blnalre esL falL d'un noud conLenanL un enLler eL
appele l'eLlqueLLe. un noud a evenLuellemenL un sous-arbre gauche eL/ou un sous-arbre drolL qul
sonL aussl des arbres blnalres. volcl une represenLaLlon d'un arbre blnalre :
73
Cn veuL deflnlr l'lnLerface BinaryTreeInterface d'une classe BinaryTree. ll fauL blen sr
une foncLlon getLabel() qul fournlL l'eLlqueLLe du noud raclne. uls, on deflnlL la meLhode
getLeftSubtree() qul fournlL le sous-arbre gauche sl celul-cl exlsLe, null slnon. Cn falL de
mme pour le sous-arbre drolL. Cn obLlenL :
public interface BinaryTreeInterface
{
/** Returns the root label of the tree. /
public int getLabel() ;
/** Returns the left subtree if there is one,
* null otherwise.
*/
public BinaryTreeInterface getLeftSubtree() ;
/** Returns the right subtree if there is one,
* null otherwise.
*/
public BinaryTreeInterface getRightSubtree() ;
}
Cecl n'esL que l'une des dlfferenLes manleres de modellser les arbres blnalres. CeLLe lnLerface
caracLerlse un arbre blnalre mals elle ne dlL rlen de la mls en ouvre de ceL arbre.
Concevolr les lnLerfaces des ob[eLs elemenLs du probleme esL une phase essenLlelle de
la concepLlon.
nous remarquons que l'lnLerface ne llsLe pas de consLrucLeur. Mals cependanL, les Lrols foncLlons de
l'lnLerface deflnlssenL ce que l'on peuL demander a un arbre blnalre. Ce que ne dlL pas l'lnLerface,
c'esL l'lmplemenLaLlon de ces foncLlons qul peuL Lre varlable.
6.4.2. Lxemp|e : une |mp|mentat|on de |'|nterface 8|nary1reeInterface
uans ceLLe lmplemenLaLlon, une classe BinaryTree lmplemenLanL l'lnLerface
BinaryTreeInterface conLlendra un aLLrlbuL pour l'eLlqueLLe (label) eL deux aLLrlbuLs pour
les sous-arbres. Ces deux dernlers aLLrlbuLs seronL evenLuellemenL null s'll n'y a pas de sous-arbres.
76
public class BinaryTree
implements BinaryTreeInterface
{
private final int label ;
private final BinaryTree leftSubtree ;
private final BinaryTree rightSubtree ;
public BinaryTree(int label,
BinaryTree leftSubtree,
BinaryTree rightSubtree)
{
this.label = label ;
this.leftSubtree = leftSubtree ;
this.rightSubtree = rightSubtree ;
}
public int getLabel()
{
return label ;
}
public BinaryTree getLeftSubtree()
{
return leftSubtree ;
}
public BinaryTree getRightSubtree()
{
return rightSubtree ;
}
}
6.S. L'|nterface, out|| contractue|
L'lnLerface esL un conLraL.
Cuand une classe declare qu'elle lmplemenLe une lnLerface, c'esL une sorLe de conLraL qu'elle slgne.
6.S.1. Lxemp|e : |'|nterface ueue
renons le cas de |'|nterface Queue dans les Co||ect|ons de Iava
4
dans le package java.util.
une queue en lnformaLlque esL une sLrucLure de donnees conLenanL des ob[eLs a la manlere d'une
flle d'aLLenLe. La premlere donnee arrlvee dans la queue sera la premlere sorLle d'ou l'acronyme
lllC (fltst lo, fltst oot). ll exlsLe des varlanLes dans la noLlon de queue, nous nous occupons de la plus
slmple.
4
Les CollecLlons de !ava, sur lesquelles nous revlendrons, sonL un ensemble de classes conLenanL des classes eL
des lnLerfaces pour les prlnclpales sLrucLures de donnees connues en lnformaLlque.
77
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Queue. Cherchez la documenLaLlon de Queue, examlnez-la.
volcl l'ensemble des meLhodes declarees dans l'lnLerface Queue eL donnee par la documenLaLlon :
Cn volL des meLhodes declarees dlrecLemenL dans l'lnLerface Queue : add, element, offer,
peek, pull eL remove. Cn volL d'auLres meLhodes du package java.util.Collection
auxquelles nous ne nous lnLeresserons pas lcl.
6.S.2. Lxemp|e : une |mp|mentat|on de |'|nterface ueue
une classe peuL lmplemenLer l'lnLerface Queue. Llle s'engage alors a proposer les meLhodes
declarees dans l'lnLerface. C'esL le cas, enLre auLres, de la classe LinkedList du package
java.util.Collection.
Cu'esL-ce qu'une llsLe chainee (LinkedList) ? une llsLe chainee esL une sLrucLure de donnees
permeLLanL de represenLer une sulLe d'ob[eLs du mme Lype. Llle esL reallsee a l'alde d'ob[eLs
auxlllalres, les palres, llees par des references : une palre possede une reference sur la palre sulvanLe.
volcl la represenLaLlon graphlque d'une llsLe d'ob[eLs A,B,C :
78
Sl nous voulons ra[ouLer un elemenL D en fln de la llsLe chainee d'ob[eLs A,B,C :
Sl nous voulons reLlrer le premler elemenL A de la llsLe chainee d'ob[eLs A,B,C,D :
Cn volL slmplemenL que l'on peuL uLlllser une sLrucLure de llsLe chainee pour lmplemenLer une flle
d'aLLenLe :
A[ouLer un ob[eL dans la flle d'aLLenLe revlenL a a[ouLer ceL ob[eL en fln de llsLe.
rendre le premler ob[eL dans la llsLe d'aLLenLe, c'esL prendre le premler ob[eL de la llsLe eL le
reLlrer.
Les concepLeurs de la classe LinkedList onL donc declare que ceLLe classe rempllssalL le conLraL
deflnl par l'lnLerface Queue eL lls onL lmplemenLes les meLhodes llsLees plus hauL. noLons que cela
n'empche pas la classe LinkedList de proposer blen d'auLres meLhodes speclflques aux llsLes
chainees.
79
u'auLres classes peuvenL lmplemenLer l'lnLerface Queue. Alnsl, la classe ArrayDeque lmplemenLe
l'lnLerface Queue en uLlllsanL une Lable du mme genre que les ArrayList. La classe
PriorityQueue lmplemenLe l'lnLerface Queue mals consldere que cerLalns elemenLs peuvenL
Lre prlorlLalres.
6.6. L'|nterface, out|| d'encapsu|at|on
L'lnLerface esL un ouLll d'encapsulaLlon.
Ln uLlllsanL |'|nterface comme un type pour une var|ab|e, on resLrelnL l'acces aux meLhodes de
l'ob[eL. Cn peuL se servlr de l'lnLerface comme Lype pour une varlable.
Lxemp|e :
Queue q = new LinkedList() ;
Seules les meLhodes de q declarees dans l'lnLerface Queue sonL accesslbles. Les auLres meLhodes de
la classe LinkedList sonL cachees. Alors que l'ob[eL q esL une llsLe chainee de la classe
LinkedList, LouLes les operaLlons posslbles sur une llsLe chainee sonL lnaccesslbles. q esL
devenue une flle d'aLLenLe du Lype Queue eL le programmeur esL obllge de s'en servlr comme d'une
flle d'aLLenLe. ll ne peuL plus s'en servlr comme d'une LinkedList.
6.7. L'|nterface, une vue part|cu||re
L'lnLerface permeL de presenLer des vues dlfferenLes d'un ob[eL.
8evenons a noLre programme de banque. Chaque compLe a un gesLlonnalre de compLe aLLlLre qul a
acces a LouLes les operaLlons. Les auLres gesLlonnalres de la banque peuvenL consulLer les
lnformaLlons sur le compLe mals n'onL pas le drolL d'y reallser des operaLlons. our reallser cela, on
declarera deux lnLerfaces :
RestrictedAccountInterface pour les gesLlonnalres ordlnalres ,
FullAccountInterface pour le gesLlonnalre du compLe.
L'ob[eL fournl aux deux Lypes de gesLlonnalres esL blen le mme mals les posslblllLes d'acces aux
meLhodes de l'ob[eL ne sonL pas les mmes.
Alnsl :
public interface RestrictedAccountInterface
{
public String getHolderName() ;
public int getAccountNumber() ;
public double getBalance() ;
}
80
uls, dans le programme du gesLlonnalre de compLe ordlnalre, on uLlllsera :
RestrictedAccountInterafce account = bank.getAccountByNumber(1234) ;
Alnsl, le compLe esL accesslble mals proLege des operaLlons non voulues car ll n'esL connu que
comme un RestrictedAccountInterface.
Ln revanche, pour le gesLlonnalre du compLe :
public interface FullAccountInterface
{
public String getHolderName() ;
public int getAccountNumber() ;
public double getBalance() ;
public void deposit(double amount) ;
public void withdraw(double amount) ;
}
uls, dans le programme du gesLlonnalre de compLe :
FullAccountInterafce account = bank.getAccountByNumber(1234) ;
Alnsl, le compLe esL accesslble mals ll n'esL pas proLege des operaLlons non voulues.
6.8. L'|nterface, des propr|ts en commun
Les lnLerfaces sonL uLlllsees quand les ob[eLs non relles enLre eux onL des proprleLes en
commun.
ues classes sonL llen enLre elles peuvenL lmplemenLer la mme lnLerface. uans ce cas, on dlra que
l'lnLerface decrlL une proprleLe que des classes peuvenL lmplemenLer. nous y revlendrons au
momenL ou nous parlerons de |'hr|tage.
Lxemp|e. renons l'exemple d'un edlLeur graphlque permeLLanL de desslner en uLlllsanL des formes
predeflnles : carre, recLangle, cercle, eLc. ll y aura donc des classes Square, Rectangle,
Circle, eLc. L'edlLeur comprendra une zone de dessln sur laquelle seronL desslnees els dlfferenLes
flgures. La zone de dessln sera represenLee par un ob[eL de la classe Graphics (nous verrons cela
plus loln). 1ous ces ob[eLs graphlques devronL lmplemenLer l'lnLerface Drawable :
public interface Drawable
{
public void paint(Graphics g) ;
}
Crce a ceL lnLerface, le programme de l'edlLeur pourra fournlr un ob[eL g de Lype Graphics eL
demander a Lous les ob[eLs graphlques de se desslner en envoyanL le message paint(g) a chacun
d'eux.
Sl l'uLlllsaLeur de l'edlLeur graphlque demande l'afflchage d'une grllle pour l'alder a poslLlonner les
ob[eLs, celle-cl ne sera pas de mme naLure que les ob[eLs graphlques cercle, recLangle, eLc. Mals elle
devra neanmolns Lre capable de s'afflcher sur l'ecran. Ln falL, la seule proprleLe commune enLre les
ob[eLs graphlques eL la grllle esL la meLhode paint. Cn declarera donc :
81
public class Grid
implements Drawable
{
public void paint(Graphics g)
{
}
}
Alnsl declaree, le programme de l'edlLeur LralLera la grllle de Lype Grid comme les flgures au
momenL de desslner. LL cecl blen que la grllle eL les flgures solL de naLures dlfferenLes.
6.9. Le po|nt sur |es |nterfaces
nous avons vu dlfferenLs usages des lnLerfaces :
L'|nterface comme out|| de concept|on. Cn decrlL les lnLerfaces de chacun des ob[eLs d'un
probleme avanL d'lmplemenLer ces lnLerfaces par des classes. Cn pense |'|nterface avant de
penser |a c|asse.
L'|nterface comme engagement contractue|. L'lnLerface esL vue comme un conLraL que la
classe dolL respecLer.
L'|nterface comme out|| d'encapsu|at|on. L'lnLerface permeL de ne monLrer qu'une facette
d'un ob[eL en dlsslmulanL le resLe.
L'|nterface comme descr|pt|f de propr|ts. L'lnLerface permeL de decrlre une proprleLe
parLagee par dlfferenLes classes qul n'onL a prlorl aucun llen enLre elles.
83
7. nr|tage de c|asses
7.1. La re|at|on d'hr|tage
Lorsque l'on declare une classe, ll esL posslble de declarer qu'elle her|te d'une auLre
classe.
La classe qul herlLe esL appelee c|asse f|||e ou sous-c|asse. La classe donL on herlLe esL appelee c|asse
mre ou super-c|asse. La classe fllle herlLe des declaraLlons falLes dans la clase mere. ll exlsLe une
noLaLlon graphlque pour cela :
7.2. Lnr|ch|ssement vs. kedf|n|t|on
Lorsque l'on declare qu'une classe herlLe d'une auLre classe, ll esL posslble d'enrlchlr la classe fllle
avec des aLLrlbuLs eL des meLhodes supplemenLalres. Cn parle alors d'enr|ch|ssement ou d'extens|on
modu|a|re. ll esL egalemenL posslble de redeflnlr des meLhodes herlLees en donnanL une nouvelle
lmplemenLaLlon de ces meLhodes. Cn parle alors de redf|n|t|on ou de subst|tut|on. LnrlchlssemenL
eL redeflnlLlon ne sonL pas excluslfs.
84
7.2.1. Lxemp|e de redf|n|t|on
volcl une classe Item represenLanL les arLlcles d'un magasln. Cn y Lrouve un prlx neL eL un prlx 11C
avec une 1vA a 20 :
public class Item
{
private double netPrice ;
public double getNetPrice()
{
return netPrice ;
}
public double getVat() // VAT = Value Added Tax
{
return 0.185 * getNetPrice() ;
}
public double getATIPrice()
{
return getNetPrice() + getVat() ;
}
}
Le moL cle extends permeL de declarer la relaLlon d'herlLage.
La classe LuxuryItem esL la classe des arLlcles de luxe d'un magasln. Cn declare qu'elle herlLe de la
classe Item eL on y redeflnlL la 1vA avec un Laux de 33 :
public class LuxuryItem extends Item
{
@Override
public double getVat()
{
return 0.33 * getNetPrice() ;
}
}
@Override esL une annotat|on. Llle esL une lndlcaLlon desLlnee au compllaLeur pour lul slgnlfler
qu'll s'aglL d'une redeflnlLlon de meLhode. Le compllaLeur verlflera que c'esL blen le cas.
L'annoLaLlon @Override n'esL pas obllgaLolre mals forLemenL recommandee.
83
7.2.2. Lxemp|e d'enr|ch|ssement
Conslderons un arLlcle de luxe parLlculler dans noLre magasln : les Lelevlslons. La classe TV herlLera
de la classe LuxurylLem eL on l'enrlchlra :
public class TV extends LuxuryItem
{
private int voltage ;
private int screenSize ;
public int getVoltage()
{
return voltage ;
}
public int getScreenSize()
{
return screenSize ;
}
}
7.3. L'arbre d'hr|tage
Ln !ava, chaque classe herlLe au plus d'une seule classe. Cn dlL que !ava praLlque l'hr|tage s|mp|e. Sl
une classe n'herlLe d'aucune auLre classe, elle herlLe par defauL de la classe Object du package
java.lang.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Object. Cherchez la documenLaLlon d'Object, examlnez-la.
Cn represenLe la relaLlon d'herlLage enLre les classes par un arbre : l'arbre d'hr|tage. La classe
Object n'esL en general pas represenLee lorsque l'on desslne l'arbre d'herlLage. Lxemple :
Acces
86
7.4. Accs |a c|asse mre
1ouL ce qul esL declare public dans la classe mere esL blen sr accesslble dans la classe fllle. 1ouL
ce qul esL declare private, comme les aLLrlbuLs, exlsLe mals n'esL pas dlrecLemenL accesslble dans
la classe fllle. u'ou la necesslLe de la meLhode
public double getNetPrice()
dans la classe Item. 8evenons sur ces deux classes. u'abord la casse Item :
public class Item
{
private double netPrice ;
public double getNetPrice()
{
return netPrice ;
}
}
puls la classe LuxuryItem :
public class LuxuryItem extends Item
{
@Override
public double getVat()
{
return 0.33 * getNetPrice() ;
}
}
L'uLlllsaLlon de getNetPrice() dans LuxuryItem esL necessalre car netPrice dolL, pour des
ralsons d'encapsulaLlon des donnees, Lre declaree private. Ln plus des moLs cles public ou
private, ll esL posslble d'uLlllser le moL cle protected.
une meLhode ou un aLLrlbuL declare protected n'esL accesslble que depuls les classes
du mme package ou depuls les classes fllles du mme package ou de LouL auLre
package.
ll esL donc posslble, mals pas recommande, de permeLLre que la classe LuxuryItem alL acces a
l'aLLrlbuL netPrice de la classe Item en le quallflanL de protected dans la classe Item.
87
Cela donne :
public class Item
{
protected double netPrice ;
public double getNetPrice()
{
return netPrice ;
}
}
eL :
public class LuxuryItem extends Item
{
@Override
public double getVat()
{
return 0.33 * netPrice ;
}
}
un aLLrlbuL declare protected ne respecte pas le prlnclpe d'encapsulaLlon des
donnees.
Ln effeL, un ob[eL de la classe fllle ou d'une classe du mme package peuL modlfler l'aLLrlbuL sans
aucun conLrle. Cn preferera uLlllser un qettet comme dans la premlere verslon de l'exemple.
C'esL pourquol on reservera l'uLlllsaLlon du moL cle protected a des meLhodes donL
on deslre auLorlser eL reserver l'usage aux classes flles.
7.S. nr|tage et constructeurs
uans le cas ou la classe mere possede des consLrucLeurs, els consLrucLeurs de la classe
fllle dolvenL lmperaLlvemenL appeler un consLrucLeur de la classe mere.
L'appel du consLrucLeur de la classe mere dolL Lre la prem|re |nstruct|on du consLrucLeur de la
classe fllle. L'appel du consLrucLeur de la classe mere esL reallse grce au moL cle super sulvl des
parameLres enLre parenLheses.
Lxemp|e. SolL la classe Point :
88
public class Point
{
private int x ;
private int y ;
public Point(int x, int y)
{
this.x = x ;
this.y = y ;
}
}
LL l'on deflnlL la classe ColouredPoint qul esL un Point enrlchl d'une couleur :
public class ColouredPoint extends Point
{
private Color color ;
public ColouredPoint(int x, int y, Color color)
{
super(x,y) ;
this.color = color ;
}
}
7.6. Le po|ymorph|sme
Conslderons une classe Shape pour decrlre des flgures dans un plan. Les flgures onL LouLes des
coordonnees :
public class Shape
{
private int x ;
private int y ;
public Shape(int x, int y)
{
this.x = x ;
this.y = y ;
}
}
89
La classe Rectangle serL a represenLer les recLangles. Ln plus des coordonnees, les recLangles onL
une hauLeur eL une largeur :
public class Rectangle extends Shape
{
private int width ;
private int height ;
public Rectangle(int x, int y, int width, int height)
{
super(x,y) ;
this.width = width ;
this.height = height ;
}
}
La classe Square serL a represenLer un carre qul n'esL auLre qu'un recLangle donL la hauLeur eL la
largeur sonL les mmes :
public class Square extends Rectangle
{
public Square(int x, int y, int width)
{
super(x,y,width,width) ;
}
}
La classe Circle esL une flgure qul a un rayon :
public class Circle extends Shape
{
private int radius ;
public Circle(int x, int y, int radius)
{
super(x,y) ;
this.radius = radius ;
}
}
LL pour flnlr la classe Point qul esL une flgure mals ne necesslLe pas d'auLres lnformaLlons que les
coordonnees :
public class Point extends Shaep
{
public Point(int x, int y)
{
super(x,y) ;
}
}
90
Cn obLlenL alors l'arbre d'herlLage sulvanL :
un ob[eL carre esL aussl un recLangle eL ll esL aussl une flgure. 1echnlquemenL, un ob[eL de la classe
Square possede les Lrols Lypes Square, Rectangle eL Shape. ue mme un ob[eL de la classe
8ecLangle possede les deux Lypes Rectangle eL Shape. Mals ll ne possede pas le Lype Square.
Les ob[eLs des classes Point, Square, Rectangle eL Circle onL Lous le Lype Shape.
un ob[eL esL Lou[ours |nstance d'une classe, sa classe de creaLlon. Alnsl, sl nous ecrlvons :
Square square = new Square(10,10,0) ;
l'ob[eL reference par la varlable square esL de Lype Square. Mals comme nous l'avons dlL plus
hauL, un ob[eL de Lype Square esL aussl un ob[eL de Lype Rectangle. 8len n'empche d'ecrlre :
Rectangle rectangle = new Square(10,10,0) ;
L'ob[eL reference par la varlable rectangle esL blen de Lype Rectangle mals ll esL lnsLance de la
classe Square.
Cuand des ob[eLs peuvenL avolr plusleurs Lypes, on parle de po|ymorph|sme.
volcl encore un exemple d'appllcaLlon du polymorphlsme :
ArrayList<Shape> shapesList = new ArrayList<Shape>() ;
shapesList.add(new Square(0,0,10)) ;
shapesList.add(new Rectangle(0?0,10,20)) ;
shapesList.add(new Circle(0,0,10)) ;
shapesList.add(new Point(55,66)) ;
7.7. L|a|son dynam|que de mthode
uans LouLes nos classes de flgures, nous a[ouLons une meLhode print() qul ecrlL une descrlpLlon
de l'ob[eL sur la console :
91
uans la classe Shape :
public void print()
{
System.out.print("Shape: x=" + x + " y=" + y) ;
}
uans la classe Point :
public void print()
{
System.out.print("Point: x=" + x + " y=" + y) ;
}
uans la classe Rectangle :
public void print()
{
System.out.print("Point: x=" + x + " y=" + y
+ " width=" + width
+ " height=" + height) ;
}
uans la classe Square :
public void print()
{
System.out.print("Point: x=" + x + " y=" + y
+ " width=" + width) ;
}
uans la classe Circle :
public void print()
{
System.out.print("Point: x=" + x + " y=" + y
+ " radius=" + radius) ;
}
Supposons une varlable shape de Lype Shape eL l'lnsLrucLlon sulvanLe :
shape.print() ;
Cuelle meLhode l'ob[eL shape dolL-ll execuLer lors de l'appel shape.print() ? Cn lmaglne que sl
shape conLlenL une reference sur un ob[eL lnsLance que la classe Circle, ll faudralL execuLer la
meLhode print() de la classe Circle. ue mme sl shape conLlenL un ob[eL de la classe
Rectangle, ll faudralL execuLer la meLhode print() de la classe Rectangle. LL alnsl de sulLe
pour chacune des classes fllles de la classe Shape.
Le probleme, c'esL qu'au momenL de la compllaLlon, quand le compllaLeur examlne l'lnsLrucLlon
shape.print(), ll esL lncapable de savolr quelle esL la classe d'lnsLanclaLlon de l'ob[eL reference
par la varlable shape.
92
ueux sLraLegles sonL posslbles :
La recherche stat|que de mthode. le compllaLeur consldere que le Lype declare de la varlable
shape esL Shape eL ll declde que c'esL la meLhode print() de la classe Shape qul dolL Lre
execuLee. Le moL sLaLlque slgnlfle, lcl, que la meLhode qul sera execuLee esL deLermlnee au
momenL de la compllaLlon. Cn parle alors de ||a|son stat|que.
La recherche dynam|que de mthode. Le compllaLeur programme une recherche de la meLhode
print() basee sur la classe d'lnsLanclaLlon de l'ob[eL reference au momenL de l'execuLlon. Le
moL dynamlque slgnlfle que la meLhode execuLee ne sera deLermlnee qu'au momenL de
l'execuLlon. Cn parle alors de ||a|son dynam|que.
!ava praLlque la recherche dynam|que de meLhode.
!ava esL un |angage ||a|son dynam|que.
La meLhode execuLee lors de l'appel shape.print() esL deLermlnee au momenL de l'execuLlon
du programme. !ava regarde quelle esL la classe d'lnsLanclaLlon de l'ob[eL reference par la varlable
shape eL cholslL la meLhode print() de ceLLe classe. Ce mecanlsme, forL blen lmplemenLe, ne
coLe pas cher en Lemps d'execuLlon.
Lxemp|e.
ArrayList<Shape> shapesList =
Iterator<Shape> iterator = shapesList.iterator() ;
while (iterator.hasNext()) {
Shape shape = iterator.next() ;
shape.print() ;
}
7.8. Le mot c| f|na| sur une mthode
!ava praLlque la recherche dynamlque de meLhode. C'esL au momenL de l'execuLlon qu'll deLermlne
la meLhode a execuLer. Mme sl le mecanlsme esL Lres efflcace, ll a quand mme un coL. ll exlsLe
neanmolns des cas ou ll esL posslble de se passer de la recherche dynamlque de meLhode. C'esL
lorsque la meLhode a execuLer peuL Lre deLermlnee sLaLlquemenL au momenL de la compllaLlon.
8a[ouLons une meLhode dans la classe Shape :
public void println()
{
print() ;
System.out.println() ;
}
CeLLe meLhode n'a pas besoln d'Lre redeflnle dans les sous-classes : elle esL correcLe pour Lous les
Lypes de flgures. uonc pour un appel a shape.println(), ll esL lnuLlle de praLlquer la recherche
dynamlque de meLhode car la meLhode qul sera execuLee esL connue, ce sera celle (unlque) de la
classe Shape.
Nous |e savons ! Mals le compllaLeur n'a aucun moyen de le savolr. Cuand ll complle la classe
Shape, ll ne peuL savolr sl la meLhode println() a eLe redeflnle ou pas dans une de ses sous-
classes. C'esL donc au programmeur d'lndlquer, grce au moL cle final, que ceLLe meLhode ne sera
pas redeflnle :
93
public final void println()
{
print() ;
System.out.println() ;
}
Crce a ceLLe declaraLlon, le compllaLeur salL que la meLhode ne sera pas redeflnle dans les sous-
classes. un bon compllaLeur evlLera de programmer une recherche dynamlque de meLhode. Le
compllaLeur esL vlgllanL : quand ll complle les sous-classes de la classe Shape, ll lnLerdlL la
redeflnlLlon de la meLhode println().
L'ut|||sat|on du mot c| final pour |es mthodes qu| ne seront pas redf|n|es et pour
|es attr|buts constants permet au comp||ateur de ra||ser des opt|m|sat|ons qu|
am||orent |a v|tesse d'excut|on des programmes.
7.9. Le mot c| f|na| sur une c|asse
Le moL cle final peuL aussl quallfler une classe. C'esL le cas de la classe String proposee par !ava.
ll n'esL pas posslble d'herlLer d'une classe declaree final. Les meLhodes d'une classe declaree
final sonL lmpllclLemenL declarees final.
7.10. Le mot c| f|na| sur une var|ab|e
Le moL cle final peuL aussl quallfler les parameLres ou les varlables locales a une meLhode.
Lxemp|e.
public void doSomething(final int x)
{
final int n = ;
}
Le moL cle final serL a dlre que ces varlables ne changeronL pas de valeurs apres leur lnlLlallsaLlon.
Mals en falL, le compllaLeur !ava esL parfalLemenL capable de deLermlner sl le programme modlfle
une varlable eL d'en Lenlr compLe. LL donc la quallflcaLlon final ne serL qu'au programmeur pour
lndlquer qu'll veuL Lre sr que la varlable ou le parameLre ne sera pas modlfle. Le compllaLeur
verlflera qu'aucune lnsLrucLlon lnLempesLlve ne modlfle la valeur du parameLre ou de la varlable.
7.11. nr|tage s|mp|e et mu|t|p|e
L'herlLage esL dlL s|mp|e sl chaque classe herlLe au plus d'une classe. C'esL le cas en !ava, Small1alk eL
Ada. L'herlLage esL alors maLerlallse par un arbre ou une forL d'arbres.
L'herlLage esL dlL mu|t|p|e sl une classe peuL herlLer de plusleurs classes. C'esL le cas en Llffel eL en
C++. uans ce cas, l'herlLage esL maLerlallse par un ou plusleurs graphes orlenLes.
Ln Iava, |'hr|tage de c|asse est s|mp|e.
94
7.12. La s|gn|f|cat|on de |'hr|tage
L'herlLage a une foncLlon de mod||sat|on :
LLanL donne une classe d'ob[eLs, on la parLlLlonne en sous-classes. Alnsl, la classe Shape
peuL Lre part|t|onne en des sous-classes speclallsees Circle, Square, eLc.
LLanL donne une classe d'ob[eLs, on peuL la raff|ner en creanL une sous-classe. ar exemple,
une classe generallsLe d'eLudlanL Student peuL Lre speclallsee en une classe
TPTStudent decrlvanL en plus les speclflclLes des eleves de 1elecom arls1ech.
L'herlLage a une foncLlon d'arch|tecture |og|c|e||e :
Les sous-classes d'une classe parLagenL le code des meLhodes eL les aLLrlbuLs de la classe
mere.
La relaLlon d'herlLage peuL avolr de nombreuses slgnlflcaLlons :
. est une sorte de .
. est un genre de .
. est une catgor|e de .
Alnsl, une TV esL une sorLe d'Item.
. est une extens|on de .
Alnsl, un ColouredPoint esL une exLenslon de Point.
. est une spc|a||sat|on de .
. est un cas part|cu||er de .
Alnsl, un LuxuryItem esL une speclallsaLlon d'Item.
Sans oubller le slmple parLage de code.
7.13. L'exemp|e des art|c|es
volcl l'exemple des arLlcles d'un magasln Lel que developpe [usqu'lcl :
nous l'eLendons avec une classe Iron represenLanL les fers a repasser :
93
La classe TV herlLe de la classe LuxuryItem car elle esL conslderee comme eLanL un arLlcle de luxe.
La classe Iron herlLe de la classe Item car un fer a repasser n'esL pas un arLlcle de luxe. Mals les
classes TV eL Iron onL en commun une meLhode getVoltage() qul caracLerlse les apparells
elecLrlques. nous pouvons eL nous devons maLerlallser cela par une lnLerface Electrical :
public interface Electrical
{
public int getVoltage() ;
}
Cn obLlenL alors :
Ln lnLrodulsanL l'lnLerface Electrical, nous nous donnons la posslblllLe de conslderer des
sLrucLures de donnees conLenanL des Electrical. ar exemple :
ArrayList<Electrical> allElectricals ;
allElectricals.add(new TV()) ;
allElectricals.add(new Iron()) ;
96
ldealemenL, ll faudralL lnLrodulre des lnLerfaces pour chacune des proprleLes speclflques des arLlcles.
ar exemple, l'lnLerface WithScreen :
public interface WithScreen
{
public int getScreenSize() ;
}
Cn aura alors :
Sl l'on lnLrodulL les Computer :
97
Comme ces dlagrammes de classes peuvenL devenlr Lres compllques, ll esL posslble d'oubller les
lnLerfaces quand nous le desslnons :
7.14. Les c|asses abstra|tes
8emarquons, que d'apres l'arbre d'herlLage cl-dessus, un ob[eL de la classe LuxuryItem sera
obllgaLolremenL une lnsLance de la classe TV ou Computer. Creer dlrecLemenL une lnsLance de la
classe LuxuryItem n'a aucun sens car un LuxuryItem dolL Lre un verlLable arLlcle.
Une c|asse qu'on ne peut |nstanc|er est appe|e une c|asse abstra|te en Iava par
oppos|t|on aux c|asses concrte que |'on peut |nstanc|er.
LuxuryItem esL donc une classe absLralLe Landls que TV eL Computer sonL des classes concreLes.
Sur le dessln qul sulL, les classes absLralLes sonL marquees par les caracLeres (A) :
98
our declarer qu'une classe esL absLralLe, on uLlllse le moL cle absLracL :
public abstract class Item
{
}
public abstract class LuxuryItem extends Item
{
}
public class TV extends LuxuryItem
{
}
Ln declaranL qu'une classe esL absLralLe, on s'lnLerdlL de creer des lnsLances dlrecLes de la classe. Le
compllaLeur esL vlgllanL : une lnsLrucLlon new Item() provoquera une erreur a la compllaLlon. ll
esL quand mme posslble de declarer des varlables donL le Lype esL une classe absLralLe :
Item item = new Computer() ;
7.1S. Les mthodes abstra|tes
8eprenons l'exemple des flgures dans le plan :
La classe Shape ne dolL pas Lre lnsLanclee. Seules les sous-classes dolvenL l'Lre. Llle dolL donc Lre
declaree absLralLe :
99
nous avlons une meLhode print()eL une meLhode println() ans la classe Shape :
CeLLe meLhode print() de la classe Shape eLalL necessalre pour que le compllaLeur sache que
LouLes les flgures concreLes onL une meLhodes print(). CependanL, la meLhode print() dans la
classe Shape ne sera [amals execuLee. Ln effeL, Lous les ob[eLs ayanL le Lype Shape seronL des
lnsLances des sous-classes concreLes de Shape qul onL LouLes leurs propres meLhodes print().
Les lnsLrucLlons de la meLhode print() de la classe Shape sonL donc lnuLlles. !ava propose de
quallfler ceLLe meLhode d'absLralLe grce au moL cle abstract. ll esL alors lnuLlle de meLLre le
corps de la meLhode :
public abstract class Shape
{
public abstract void print() ;
public final void println()
{
print() ;
System.out.println() ;
}
}
une meLhode declaree abstract esL deflnle par son en-LLe eL n'a pas de corps.
100
ulsque la classe Shape esL declaree absLralLe, le compllaLeur n'accepLera pas la creaLlon d'une
lnsLance dlrecLe de la classe Shape avec une lnsLrucLlon new Shape(). Comme la meLhode
print() esL declaree absLralLe, une sous-classe de la classe Shape qul ne donne pas une
lmplemenLaLlon de ceLLe meLhode devra Lre aussl declaree absLralLe.
7.16. Une nouve||e mod||sat|on des artc||es
MalnLenanL que nous connalssons les classes eL les meLhodes absLralLes, nous allons proposer une
modellsaLlon dlfferenLe des arLlcles d'un magasln. nous commenons par la raclne de l'arbre
d'herlLage. Ce sera la classe Item qul conLlenL ce qul esL communs a Lous les arLlcles. CeLLe classe
sera sous-classee Lrols fols :
La classe absLralLe EssentialItem des arLlcles de premlere necesslLe avec une 1vA a 3 .
La classe absLralLe OrdinaryItem des arLlcles ordlnalres avec une 1vA a 18,3 .
La classe absLralLe LuxuryItem des arLlcles de luxe avec une 1vA a 33 .
Commenons par la classe Item :
public abstract class Item
{
public Item(String denomination)
{
this.denomination = denomination ;
}
private final String denomination ;
public final String getDenomination()
{
return denomination ;
}
public abstract double getNetPrice() ;
public abstract double getVat() ;
public final double getATIPrice()
{
return getNetPrice() + getVAT() ;
}
}
Les Lrols classes sulvanLes sonL absLralLes pour des ralsons loglques : ll n'y a aucun sens a creer une
lnsLance dlrecLe de ces classes. Ces classes sonL aussl absLralLes car elle n'lmplemenLe pas la
meLhode getNetPrice().
101
La classe EssentialItem :
public abstract class EssentialItem extends Item
(
public EssentialItem(String denomination)
{
super(denomination) ;
}
public final double getVat()
{
return 0,05 * getNetPrice() ;
}
}
La classe OrdinaryItem :
public abstract class OrdinaryItem extends Item
(
public OrdinaryItem(String denomination)
{
super(denomination) ;
}
public final double getVat()
{
return 0,185 * getNetPrice() ;
}
}
La classe LuxuryItem :
public abstract class LuxuryItem extends Item
(
public LuxuryItem(String denomination)
{
super(denomination) ;
}
public final double getVat()
{
return 0,33 * getNetPrice() ;
}
}
102
Ce qul donne l'arbre d'herlLage :
nous venons de proposer un modele posslble pour les classes Item, EssentialItem,
OrdinaryItem eL LuxuryItem. CeLLe modellsaLlon esL LouL a falL correcLe. CependanL.
Un bon |nformat|c|en s'|nqu|te tou[ours |orsqu'|| vo|t |es mmes |nstruct|ons
d|ffrents endro|ts de son programme. Ce|a peut tradu|re une fa|b|esse.
Les meLhodes double getVat() des Lrols sous-classes de la classe Item sonL Lres slmllalres a
l'excepLlon du Laux de 1vA qu'elles uLlllsenL. ourquol en pas sLocker ce Laux de 1vA dans un aLLrlbuL
de la classe Item. Cn obLlenL :
public abstract class Item
{
public Item(String denomination, double vatRate)
{
this.denomination = denomination ;
this.vatRate = vatRate ;
}
private final String denomination ;
public final String getDenomination()
{
return denomination ;
}
private final double vatRate ;
public final double getVAT()
{
return vatRate * getNetPrice() ;
}
public abstract double getNetPrice() ;
public final double getATIPrice()
{
return getNetPrice() + getVAT() ;
}
}
103
uls les Lrols sous-classes :
public abstract class EssentialItem extends Item
{
public EssentialItem(String denomination)
{
super(denomination,0.05) ;
}
}
public abstract class OrdinaryItem extends Item
{
public OrdinaryItem(String denomination)
{
super(denomination,0.185) ;
}
}
public abstract class LuxuryItem extends Item
{
public LuxuryItem(String denomination)
{
super(denomination,0.33) ;
}
}
Cela donne l'arbre d'herlLage sulvanL :
Ce nouveau modele des classes Item, EssentialItem, OrdinaryItem eL LuxuryItem n'esL
nl mellleur nl molns bon que le precedenL modele. Ce modele evlLe la dupllcaLlon de code observee
dans les Lrols sous-classes mals ll lnLrodulL une dose de complexlLe dans la classe raclne Item.
Chacun esL llbre de cholslr l'un ou l'auLre de ces deux modeles.
7.17. kevenons sur |es |nterfaces
our conLlnuer la modellsaLlon, nous lnLrodulsons des lnLerfaces !ava pour decrlre cerLalns aspecLs eL
cerLalnes proprleLes speclflques des arLlcles. Cn uLlllsera les lnLerfaces unlquemenL sl l'herlLage ne
permeL pas d'lmplemenLer la proprleLes.
104
Lxemp|e. La proprleLe Lre elecLrlque se LradulL par l'lnLerface Electrical :
public interface Electrical
{
public int getVoltage() ;
public int getPower() ;
}
Lxemp|e. La proprleLe WithScreen qul LradulL le falL d'avolr un ecran :
public interface WithScreen
{
public String getScreenFormat() ;
public double getDiagonalSize() ;
}
ue Lelles lnLerfaces dolvenL Lre deflnles pour chacune des proprleLes ldenLlflables de cerLalnes
caLegorles d'arLlcles.
103
Sl le magasln vend des Lelevlslons, nous lnLrodulsons une classe TV qul herlLe de LuxuryItem. une
Lelevlslon a une marque, un nom de modele, un formaL d'ecran eL une Lallle de dlagonale d'ecran.
Cela donne :
public abstract class TV extends LuxuryItem
implements Electrical, WithScreen
{
public TV(String trademark,
String model,
String screenFormat,
double diagonalSize,
int voltage,
int power)
{
super(trademark + " "
+ model + " "
+ screenFormat + " "
+ diagonalSize + " inchs",
0,33) ;
this.trademark = trademark ;
this.model = model ;
this.screenFormat = screenFormat ;
this.diagonalSize = diagonalSize ;
this.voltage = voltage ;
this.power = power ;
private final String trademark ;
private final String model ;
private final String stringFormat ;
private final double diagonalSize ;
private final int voltage ;
private final int power ;
public final int getVoltage()
{
return voltage ;
}
public final int getPower()
{
return power ;
}
public final String getStringFormat()
{
return screenFormat ;
}
public final double getDiagonalSize()
{
return diagonalSize ;
}
}
106
Supposons que la marge LlleCer ne vend que des Lelevlslons 16/9 avec une Lenslon de 220 volLs.
nous pourrlons lnLrodulre une classe absLralLe pour ces Lelevlslons :
public abstract class ElleGerTV extends TV
{
public ElleGerTV(String model, double diagonalSize, int power)
{
super("ElleGer",
model,
"16/9",
diagonalSize,
220,
power) ;
}
}
ll sufflra alors pour lmplemenLer une Lelevlslon LlleCer de fournlr ses caracLerlsLlques eL la meLhode
qul calcule son prlx.
7.18. Mod||sat|on des art|c|es
nous voyons sur ceL exemple que la modellsaLlon des arLlcles d'un magasln peuL Lre reallse de
manlere lncremenLale eL modulalre :
Incrmenta|e slgnlfle que l'on n'esL pas obllge de developper la LoLallLe de l'appllcaLlon pour
qu'elle foncLlonne. Cn peuL developper eL LesLer des parLles lsolees comme les Lelevlslons
puls passer a une auLre caLegorle d'arLlcles.
Modu|a|re slgnlfle que chaque caLegorle d'arLlcle esL modellsee par un ensemble de classes
loglquemenL lndependanLe des auLres. Cela pourra se Lradulre par l'exlsLence d'un package
dedle.
CeLLe faclllLe de developpemenL suppose que les classes de base eL les lnLerfaces onL eLe blen
conues :
Ln effeL, une modlflcaLlon a posLerlorl des lnLerfaces ou des classes de bases peuL demander
de revolr la LoLallLe du code.
Sl l'on renonce aux modlflcaLlons des lnLerfaces eL des classes de base necesslLees par un
nouveau Lype d'arLlcles alors ce nouveau Lype d'arLlcle sera mal programme.
7.19. Interfaces vs. C|asses abstra|tes
Cn uLlllsera une |nterface pour decrlre une propr|t parLagee par un cerLaln nombre
d'ob[eLs qul n'onL pas forcemenL de relaLlons d'herlLage enLre eux.
Alnsl, Electrical esL une proprleLe parLagee par cerLalns arLlcles du magasln.
Cn uLlllsera une c|asse abstra|te pour decrlre l'|dent|t d'une classe d'ob[eLs. Ces ob[eLs
onL a prlorl des proprleLes parLagees eL lmplemenLees de la mme manlere.
Alnsl, Item decrlL l'ldenLlLe d'un arLlcle de magasln.
107
7.20. Conc|us|ons
L'herlLage esL une noLlon complexe ayanL de nombreuses slgnlflcaLlons eL posanL souvenL des
problemes concepLuels. 8len modellser les elemenLs d'un probleme, c'esL-a-dlre deLermlner un arbre
d'herlLage a la fols comprehenslble, loglque eL efflcace, requlerL de la meLhode eL de l'experlence.
Comme souvenL en lnformaLlque, ll n'y a pas de meLhode absolue. lL n'y a que des approches, des
bonnes praLlques eL une meLhodologle qul foncLlonne souvenL.
109
8. Lxcept|ons et erreurs
endanL l'execuLlon d'un programme, ll peuL se produlre des erreurs. ar exemple : dlvlslon enLlere
par zero, epulsemenL de la memolre dlsponlble, acces a un ob[eL reference mals la reference esL
null, eLc. ue Lelles erreurs se produlsenL lorsque, par exemple, le programmeur a oublle d'lnlLlallser
une varlable ou blen de LesLer une condlLlon.
8.1. Les erreurs |'excut|on
Lorsqu'une erreur se produlL pendanL l'execuLlon, elle se produlL normalemenL dans une meLhode
qul a eLe appelee par une meLhode qul a eLe appelee par une auLre meLhode eL alnsl de sulLe [usqu'a
la meLhode lnlLlale main.
Cuand l'erreur se produlL, l'execuLlon du programme s'arrLe. !ava cree un ob[eL de Lype
Exception qul conLlenL des lnformaLlons relaLlves a l'erreur. Cn dlL que |'except|on est |eve.
L'excepLlon remonLe la sequence des appels de meLhodes [usqu'a la meLhode maln lnlLlale. Cn dlL
que |'except|on est propage [usqu'a la meLhode main.
Le programme s'arrLe eL un message d'erreur slgnlflcaLlf s'afflche sur la console en prenanL en
compLe les lnformaLlons collecLees par l'ob[eL excepLlon pendanL sa propagaLlon.
Sl l'on nomme A = main, B, C eL D les procedures decrlLes cl-dessus eL que l'erreur se produlL dans
D, on peuL represenLer alnsl une execuLlon sans erreur eL une execuLlon avec erreur :
110
8.2. Le message d'erreur
un message d'erreur Lyplque esL le sulvanL :
java.lang.Exception: java.lang.NullPointerException
at utils.CheckData.checkNotEmpty (CheckData.java:63)
at submission.Submission.handle (Submission.java:146)
at Main.main (Main.java:16)
Cn volL les appels lmbrlques de meLhodes : main (en bas) a appele handle ([usLe au dessus) qul a
appele checkNotEmpty. Cn volL les numeros de llgnes eL les noms des flchlers source. Cn volL
l'erreur (NullPointerException) eL la llgne du flchler ou elle s'esL produlLe. Ln falL, le message
d'erreur fournlL enormemenL d'lnformaLlons :
L'erreur esL de Lype NullPointerException, c'esL-a-dlre l'uLlllsaLlon d'une reference
null sur un ob[eL.
Llle s'esL produlLe a la llgne 63 du flchler CheckData.java dans la meLhode
checkNotEmpty de la classe CheckData du package utils.
CeLLe meLhode a eLe appelee a la llgne 146 du flchler Submission.java dans la meLhode
handle de la classe Submission du package submission.
LL flnalemenL, celle-cl a eLe appelee a la llgne 16 du flchler Main.java dans la meLhode
main de la classe Main.
8.3. Ana|yser |es erreurs
nous venons de volr de manlere generale ce qul se passe quand une erreur se produlL pendanL
l'execuLlon d'un programme. Ln !ava, ll esL Lres slmple d'ldenLlfler les boqs. Cuel Lype de boq ? Cu
s'esL-ll produlL ? nous allons enLrer dans les deLalls eL les parLlcularlLes du mecanlsme de gesLlon
d'erreur de !ava :
les dlfferenLs Lypes d'erreur ,
le LralLemenL des erreurs ,
les excepLlons deflnles par l'uLlllsaLeur.
8.4. Les d|ffrents types d'erreur
Le premler Lype d'erreur esL celul des erreurs graves qul ne peuvent pas tre tra|tes par le
programmeur eL qul provoque obllgaLolremenL l'arrL du programme. Llles sonL represenLees par
des ob[eLs de la classe Error eL non par des ob[eLs de la classe Exception. Lxemple : Out of
memory ou Virtual Machine error.
Le deuxleme Lype d'erreur esL celul des erreurs qul peuvent tre tra|tes par le programmeur. Llles
sonL represenLees par des ob[eLs de la classe Exception. Lxemple : Null Pointer
Exception.
Lee Lrolsleme Lype d'erreur esL celul des erreurs llees au langage eL qul peuvent tre tra|tes par le
programmeur. C'esL un cas parLlculler du precedenL. Llles sonL represenLees par des ob[eLs de la
classe RuntimeException qul esL une sous-classe de la classe Exception. Lxemple :
Arithmetic Error.
1ouLes les erreurs propagees par !ava sonL des sous-classes de la classe Throwable dans le
package java.lang :
111
Cuand une erreur survlenL, un ob[eL de la classe Throwable esL cree eL propage [usqu'a la
meLhode main lnlLlale. CeL ob[eL peuL Lre de Lype :
Error (erreurs graves) ,
Exception (erreurs communes) ,
une sous-classe de Exception (erreurs parLlculleres) ,
RuntimeException (erreurs llees au langage) ,
une sous-classe de RuntimeException (erreurs parLlculleres).
Les sous-classes d'Exception eL de RuntimeException sonL des speclallsaLlons represenLanL
des cas parLlcullers d'erreurs.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Exception. Cherchez la documenLaLlon d'Exception,
examlnez-la.
8.S. Le tra|tement des erreurs
ll esL posslble d'arrLer la propagaLlon d'une erreur a l'alde de l'lnsLrucLlon try-catch.
L'lnsLrucLlon try-catch s'ecrlL sous la forme :
try {
// instructions pouvant dclencher
// une erreur
} catch (Exception e) {
// instructions executer en
// cas derreur
}
une erreur peuL se produlre la ou ll y a les lnsLrucLlons pouvanL declencher une erreur. La
propagaLlon de l'erreur evenLuelle esL arrLee eL les lnsLrucLlons de subsLlLuLlon slLuees dans le bloc
catch sonL execuLees. AvanL que les lnsLrucLlons du bloc catch solenL execuLees, l'excepLlon
propagee esL recuperee dans la varlable e qul precede le bloc catch.
112
our resumer, lors de l'execuLlon d'un bloc try { } catch (Exception e) { }, les
lnsLrucLlons du bloc try sonL execuLees :
Sl aucune excepLlon n'esL levee eL propagee duranL l'execuLlon de ce bloc, on en resLe la.
Sl une excepLlon esL propagee, elle esL sLoppee eL se reLrouve dans la varlable e, puls l'on
execuLe le bloc catch.
uans le bloc caLch, le programmeur peuL :
afflcher un message d'erreur speclflque ,
corrlger les condlLlons de l'erreur eL falre un auLre calcul ,
eLc.
8.6. Lxemp|e de tra|tements (1)
une erreur grave de Lype Error ne peuL Lre reparees. Cn se conLenLe d'afflcher un message
d'erreur eL on Lermlne le programme :
public class OutOfMem
{
public static void main(String[] args)
{
int size = Integer.parseInt(args[0]) ;
try {
ArrayList<Integer> big = new ArrayList<Integer>() ;
for (int i = 0 ; i < size ; i++)
big.add(new Integer(0)) ;
} catch (Error e) {
System.out.println("Error: " + e) ;
System.exit(0) ;
}
}
}
Le premler argumenL du programme, args[0], esL Lransforme en un enLler size avec la meLhode
de classe parseInt de la classe Integer. uls on meL size fols un new Integer(0) dans la
ArrayList big. our size sufflsammenL grand, on flnlL pas consommer la LoLallLe de la memolre
eL donc lever eL propager une Error qul sera LralLer par le bloc catch. Le bloc catch afflchera :
Error: java.lang.OutOfMemoryError: Java heap space
puls s'arrLera grce a l'lnsLrucLlon System.exit(0).
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Integer. Cherchez la documenLaLlon d'Integer, examlnez
plus parLlculleremenL la meLhode parseInt.
113
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 System. Cherchez la documenLaLlon de System, examlnez
plus parLlculleremenL la meLhode exit.
8.7. Lxemp|e de tra|tements (2)
Les excepLlons de Lype RuntimeException correspondenL a des erreurs ordlnalres llees a
l'execuLlon de !ava.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 ArrayList. Cherchez la documenLaLlon de ArrayList,
examlnez plus parLlculleremenL la meLhode get(int index).
Cn volL que la meLhode get(int index) peuL declencher une excepLlon du Lype
IndexOutOfBoundsException qul esL une sous-classe de RuntimeException. CeLLe
excepLlon esL levee lorsque l'on uLlllse un lndlce pour acceder a la ArrayList mals ceL lndlce ne
correspond pas a un elemenL du Lableau. Sl l'on veuL LralLer ceLLe erreur :
ArrayList<Integer> big = ;
try {
Integer n = big.get(i) ;
} catch (Exception e) {
System.out.println("Indice hors limite dans le tableau big") ;
}
8.8. Lxemp|e de tra|tements (3)
ll esL posslble d'arrLer s|ect|vement les excepLlons.
Ln effeL, ll esL posslble d'avolr plusleurs blocs catch derrlere un bloc try :
try {
} catch (IndexOutOfBoundException e) {
} catch (ArithmeticException e) {
} cacth (Exception e) {
}
Seul le premler bloc catch donL le Lype correspond a l'excepLlon propagee arrLera l'excepLlon eL
sera execuLe. Les auLres seronL lgnores. uonc l'ordre des blocs catch esL lmporLanL.
114
8.9. La c|ause f|na||y
La clause finally esL poslLlonnee en fln d'un bloc try-catch. Llle permeL de speclfler une sulLe
d'lnsLrucLlons qul sera execuLee apres le bloc try-catch quelle que solL la manlere donL s'esL
deroule l'execuLlon de ce bloc. un usage Lres classlque de ceLLe clause concerne les enLrees-sorLles :
FileInputStream f = null ;
try {
f = ; // ouverture dun fichier en lecture
// lecture et traitement dun fichier
} catch (IOException e) {
// erreur dentre-sortie
} catch (Exception e) {
// autres erreurs
} finally {
if (f != null) // fermeture du fichier
try { f.close() ; } catch (Exception e) {}
}
Cela permeL de fermer le flchler quol qu'll arrlve !
8.10. keprer |es erreurs
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Exception. Cherchez la documenLaLlon de Exception,
examlnez plus parLlculleremenL la meLhode printStackTrace().
une meLhode lmporLanLe de la classe Exception esL la meLhode printStackTrace() eL ses
varlanLes. Llle afflche la sequence des appels de meLhodes au momenL ou se produlL l'erreur :
try {
} cacth (Exception e) {
e.printStackTrace() ;
}
CeLLe meLhode esL blen enLendu dlsponlble dans LouLes les classes qul herlLenL de Exception.
8.11. rogrammer |e dc|enchement d'une erreur
Le programmeur peuL declencher une excepLlon a l'alde de l'lnsLrucLlon throw. Cn
creee une excepLlon eL on la lance grce a throw.
lmaglnons une meLhode qul prend en argumenL un prenom eL un nom eL fabrlque le nom compleL
par concaLenaLlon. Cn commence par conLrler que les argumenLs ne sonL pas null eL sonL de
longueur superleur a zero :
113
public String computeFullName(String firstName, String lastName)
{
if (firstName == null && firstName.length() == 0)
throw new Exception("First name is invalid) ;
if (lastName == null && lastName.length() == 0)
throw new Exception("Last name is invalid") ;
return firstName + " " + lastName ;
}
Sl une meLhode esL suscepLlble de declencher une excepLlon, cela dolL Lre declare avec
le moL cle throws.
public String computeFullName(String firstName, String lastName)
throws Exception
{
if (firstName == null && firstName.length() == 0)
throw new Exception("First name is invalid") ;
if (lastName == null && lastName.length() == 0)
throw new Exception("Last name is invalid") ;
return firstName + " " + lastName ;
}
Cela ne concerne pas les erreurs de Lype RuntimeException ou Error.
8.12. Df|n|r ses propres except|ons
Le programmeur peuL deflnlr ses propres excepLlons en LanL que sous-classes de la classe
Exception.
volcl une declaraLlon d'excepLlon :
public class InvalidFirtNameException extends Exception
{
private final String name ;
public InvalidFirstNameException(String name)
{
super("Invalid first name: " + name) ;
this.name = name ;
}
public final String getName()
{
return name ;
}
}
116
uans ceLLe declaraLlon, on volL que le premler appel du consLrucLeur esL un appel au consLrucLeur de
la classe Exception qul eLabllL le message d'erreur de l'excepLlon. noLons aussl que ceL excepLlon
conLlenL une donnee embarquee, la donnee name.
Cn pourralL de mme deflnlr l'auLre Lype d'excepLlon InvalidLastNameException :
public class InvalidLastNameException extends Exception
{
private final String name ;
public InvalidLastNameException(String name)
{
super("Invalid last name: " + name) ;
this.name = name ;
}
public final String getName()
{
return name ;
}
}
LL l'on peuL redeflnlr computeFullName pour qu'elle declenche ces nouvelles excepLlons :
public String computeFullName(String firstName, String lastName)
throws InvalidFirstNameException, InvalidLastNameException
{
if (firstName == null && firstName.length() == 0)
throw new InvalidFirstNameException(firstName) ;
if (lastName == null && lastName.length() == 0)
throw new InvalidLastNameException(lastName) ;
return firstName + " " + lastName ;
}
8.13. Arrter ses propres except|ons
Le programmeur peuL arrLer ses propres excepLlons :
try {
String fullName = computeFullName(firstName,lastName) ;
} catch (InvaldFirstNameException e) {
String name = e.getName() ;
} catch (InvalidLastName e) {
String name = e.getName() ;
}
uans le bloc catch, ll esL posslble de recuperer les donnees embarquees.
117
8.14. rogrammer avec des except|ons
lo sectloo 8.14 oest pos oo ptoqtomme.
Cn peuL lmaglner d'uLlllser les excepLlons pour programmer. Conslderons les arbres blnalres qul
correspondenL a l'lnLerface sulvanLe que nous ne commenLerons pas :
public interface BTInterface
{
public int getLabel() ;
public BTInterface getLeftSubtree() ;
public BTInterface getRightSubtree() ;
}
ueflnlssons une classe fllle de la classe Found :
public class Found extends Throwable {}
La meLhode sulvanLe auxSearch, a meLLre dans la classe qul lmplemenLe les arbres blnalres,
parcourL l'arbre blnalre en y recherchanL une valeur value. Llle declenche une excepLlon de Lype
Found sl elle Lrouve ceLLe valeur :
private final void auxSearch(int value)
throws Found
{
if (getLabel() == value)
throw new Found() ;
BTInterface leftSubtree = getLeftSubtree() ;
if (leftSubtree != null)
leftSubtree.auxSearch(value) ;
BTInterafce rightSubtree = getRightSubtree() ;
if (rightSubtree != null)
rightSubtree.auxSearch(value) ;
}
CeLLe meLhode auxSearch declenche une excepLlon du Lype Found sl eL seulemenL sl son
argumenL value esL Lrouve dans l'arbre. Slnon, elle ne declenche rlen.
Cn deflnlL une meLhode search a meLLre dans la classe qul lmplemenLe les arbres blnalres, qul
execuLe la precedenLe dans un boc try-catch. S'll n'y a pas d'excepLlon Found declenchee, elle
repond false. S'll y a une excepLlon Found, elle repond true :
118
public final Boolean search(int value)
{
try {
auxSearch(value) ;
return false ;
} catch (Found e) {}
return true ;
}
Ce Lype de programmaLlon avec des excepLlons esL a deconselller.
Ln effeL, les performances du sysLeme de gesLlon des excepLlons eL des erreurs sonL Lelles que le
programme sera Lres lenL.
Lxemp|e. Supposons que l'on recherche un elemenL dans une llsLe chainee Lres grande. ll exlsLe
dlfferenLs algorlLhmes : algorlLhme lLeraLlf, algorlLhme recurslf eL blen enLendu avec les excepLlons.
volcl les Lemps d'execuLlon sur une machlne donnee :
1. 8echerche lLeraLlve : 0,0124 ms
2. 8echerche recurslve : 0,0190 ms
3. Avec les excepLlons : 0,2868 ms
L'algorlLhme avec les excepLlons esL envlron 23 fols plus lenLs que les algorlLhmes classlques.
8.1S. Conc|us|ons
Le mecanlsme de gesLlons des erreurs de !ava esL un mecanlsme Lres pulssanL. ll permeL au
programmeur d'evlLer de falre des LesLs en permanence. Le programmeur programme sa sequence
d'lnsLrucLlon comme s'll ne devalL pas y avolr d'erreurs puls ll lalsse l'erreur evenLuelle se produlre eL
recupere evenLuellemenL l'excepLlon a l'alde d'un bloc try-catch pour l'analyser. L'uLlllsaLlon des
excepLlons par le programmeur dolL Lre reservee au LralLemenL de slLuaLlons excepLlonnelles ou les
performances ne sonL pas essenLlelles.
119
9. Lntres-sort|es (I]C)
9.1. 1out est octet
1ouL esL ocLeL (byte).
ue par son hlsLolre, LouL esL ocLeL dans un ordlnaLeur eL le moL anglals byte esL parfols uLlllses pour
deslgner les ocLeLs
3
. un ocLeL esL compose de 8 blLs d'lnformaLlons 0 ou 1. La memolre esL composee
d'ocLeLs qul sonL numeroLes a parLlr de zero. Les flchlers sur dlsques sonL egalemenL composes
d'ocLeLs. Cuand deux ordlnaLeurs communlquenL, lls echangenL des ocLeLs.
Les ocLeLs sonL classlquemenL presenLes en base 16 (hexadeclmal) avec la noLaLlon 0xAB. 0x esL un
preflxe. Les deux chlffres qul sulvenL sonL dans l'ensemble 0,.,9,A.,l. Chacun d'enLre eux
represenLenL 4 blLs.
9.2. Iava I]C
Les enLrees-sorLles en !ava, L/S pour enLrees-sorLles ou l/C pour lopot/Ootpot, sonL basees sur la
noLlon de flux d'ocLeLs (byte stteom). ll y a des flux de sorLle d'ocLeLs (byte ootpot stteom) dans
lequel on ecrlL des ocLeLs. ll y a des flux d'enLree d'ocLeLs (byte lopot stteom) ou on llL des ocLeLs.
un flux d'enLree d'ocLeLs ou un flux de sorLle d'ocLeLs peuL correspondre a :
un flchler sur le dlsque dur de l'ordlnaLeur ,
une zone de memolre ,
une connexlon reseau.
9.3. Les f|ux de sort|e d'octets
La classe de base des flux de sorLle d'ocLeLs esL la classe absLralLe OutputStream. Ses sous-classes
concreLes permeLLenL d'ecrlre des ocLeLs (bytes) sur dlfferenLs supporLs.
3
un byte en anglals n'esL pas forcemenL un ocLeL, noLammenL sur de Lres vleux ordlnaLeurs. A presenL, le moL
byte deslgne un ocLeL.
120
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 OutputStream. Cherchez la documenLaLlon de
OutputStream, examlnez ses sous-classes concreLes.
Cn noLera en parLlculler les classes sulvanLes :
La classe FileOutputStream permeL d'ecrlre des ocLeLs dans des flchlers sur dlsque.
La classe ByteArrayOutputStream permeL d'ecrlre des ocLeLs en memolre.
9.4. Les f|ux d'entre d'octets
La classe de base des flux d'enLree d'ocLeLs esL la classe absLralLe InputStream. Ses sous-classes
concreLes permeLLenL de llre des ocLeLs (bytes) sur dlfferenLs supporLs.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 InputStream. Cherchez la documenLaLlon de
InputStream, examlnez ses sous-classes concreLes.
Cn noLera en parLlculler les classes sulvanLes :
La classe FileInputStream permeL de llre des ocLeLs dans des flchlers sur dlsque.
La classe ByteArrayInputStream permeL de llre des ocLeLs en memolre.
9.S. L|re |e contenu d'un f|ch|er
Cn deslre afflcher le conLenu d'un flchler, c'esL-a-dlre la sulLe des ocLeLs qul composenL le flchler. Les
ocLeLs seronL afflches sous forme hexadeclmale. ll fauL donc ouvrlr le flchler, llre les ocLeLs eL les
afflcher puls fermer le flchler. Alnsl que le monLre la documenLaLlon de !ava, LouLes ces operaLlons
d'enLrees-sorLles sonL suscepLlbles de lever des excepLlons. ll esL donc lmporLanL de meLLre ces
lnsLrucLlons dans un bloc try-catch.
Cn agencera les choses comme cecl :
FileInputStream is = null ;
try {
is = new FileInputStream("HexFile.class") ;
opetotloos Jeottes-sottles
} catch (Exception e) {
e.printStackTrace() ;
} finally {
try {
is.close() ;
} catch (Exception e) {}
}
CeLLe sLrucLure de code esL classlquemenL celle que l'on uLlllse pour falre des enLrees-sorLles. Cn
commence par declarer le flux en dehors du bloc try-catch. uls on falL les operaLlons d'enLrees-
sorLles. Sl une excepLlon se produlL, elle esL recuperee par le catch eL la plle des appels esL afflche
121
grce a la meLhode printStackTrace. uans Lous les cas, on passe par le bloc finally qul va
LenLer de fermer le flux. Cn meLLra l'lnsLrucLlon close() dans un bloc try-catch car elle peuL
produlre une excepLlon.
noLons que le compllaLeur de !ava esL vlgllanL eL qu'll salL vous slgnaler quand ll fauL un
bloc try-catch.
our ecrlre les operaLlons d'enLrees-sorLles a l'lnLerleur du bloc try-catch, on consulLe la
documenLaLlon de FileInputStream ou l'on volL que les appels a read() fournlssenL un ocLeL
sous forme d'enLler (int). Cuand le flchler esL flnl, read() fournlL -1. Cn Lransforme le resulLaL de
read() en chaine en hexadeclmale grce a la meLhode de classe toHexString de la classe
Integer. Cn compleLe avec un zero a drolLe sl le resulLaL esL lnferleur a 16 puls on l'lmprlme avec
la chaine " 0x" devant. ll fauL lmporLer java.io.*. Cela donne :
import java.io.* ;
public class HexFile
{
public static void main(String[] args)
{
FileInputStream is = null ;
try {
is = new FileInputStream("HexFile.class") ;
int b = is.read() ;
while (b != -1) {
String digits = Integer.toHexString(b) ;
if (b < 16)
digits = "0" + digits ;
System.out.println(" 0x" + digits) ;
b = is.read() ;
}
System.out.println() ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
try {
is.close() ;
} catch (Exception e) {}
}
}
}
Sl vous Lravalllez avec Lcllpse, ll fauL remplacer le nom du flchler par
"HexFile.class" par "bin/HexFile.class". Ln effeL, le programme s'execuLe
a la raclne du pro[eL eL le flchler HexFile.class esL dans le reperLolre bin.
122
9.6. I]C 8uffer|sat|on
lmaglnons un programme qul llL ou ecrlL des ocLeLs dans un flchler sur un supporL maLerlel comme
une cle uS8, un dlsque dur, eLc. Sl chaque lnsLrucLlon de lecLure ou d'ecrlLure provoque la mlse en
marche du maLerlel, le programme sera lenL eL le maLerlel ne durera pas Lres longLemps.
Cn regle ce probleme par l'uLlllsaLlon d'une zone de memolre, lnLermedlalre enLre le
programme eL supporL physlque du flux, appelee Lampon (boffet en anglals).
Le falL d'uLlllser un Lampon (boffet) s'appelle la boffetlsotloo.
9.6.1. 8uffer|sat|on en entre
Cn la schemaLlse alnsl :
Cuand un ocLeL (byte) dolL Lre lu, ll esL prls dans le Lampon (boffet) au lleu d'aller le chercher sur le
dlsque dur. Cuand le Lampon (boffet) esL vlde, on le rempllL a parLlr du dlsque dur par une seule
operaLlon de lecLure. Cela redulL le nombre d'operaLlons physlques de lecLures effecLuees sur le
dlsque. La Lallle du Lampon (boffet) esL un facLeur. !ava fournlL des Lallles par defauL.
our boffetlset un flux d'enLree d'ocLeLs en enLree, on encapsule ce flux dans un
BufferedInputStream. Cn commence par creer un flux d'ocLeLs en enLree :
FileInputStream fos = new FileInputSTream("datafile.txt") ;
uls on l'encapsule dans un BufferedInputStream :
BufferedInputStream bos = new BufferedInputStream(fos) ;
La BufferedInputStream s'uLlllse ensulLe comme le FileInputStream mals ll reallse
l'operaLlon de boffetlsotloo.
9.6.2. 8uffer|sat|on en sort|e
Cn la schemaLlse alnsl :
123
Cuand un ocLeL (byte) dolL Lre ecrlL, ll esL ecrlL dans le Lampon (boffet) pluLL que de l'ecrlre sur le
dlsque dur. Cuand le Lampon (boffet) esL pleln, on l'ecrlL sur le dlsque dur en une seule operaLlon
d'ecrlLure. Cela redulL le nombre d'operaLlons physlques de lecLures effecLuees sur le dlsque. La Lallle
du Lampon (boffet) esL un facLeur. !ava fournlL des Lallles par defauL.
our boffetlset un flux d'enLree d'ocLeLs en sorLle, on encapsule ce flux dans un
BufferedOutputStream. Cn commence par creer un flux d'ocLeLs en sorLle :
FileOutputStream fos = new FileOutputSTream("datafile.txt") ;
uls on l'encapsule dans un BufferedOutputStream :
BufferedOutputStream bos = new BufferedOutputStream(fos) ;
La BufferedOutputStream s'uLlllse ensulLe comme le FileOutputStream mals ll reallse
l'operaLlon de boffetlsotloo.
9.6.3. Attent|on
La noLlon de bufferlsaLlon esL lmporLanLe pour LouL flux qul llL ou ecrlL sur un maLerlel.
noLons aussl que comme Lres souvenL avec les flux lmbrlques, ll sufflL de fermer le plus
exLerleur pour que cela ferme les auLres. Alnsl, sl l'on ferme le
BufferedOutputStream, cela fermera aussl le FileOutputStream a parLlr
duquel ll esL consLrulL.
9.7. D|ffrents types de f|ux
Sl LouL esL ocLeL (byte), ll esL rare que les programmes dolvenL manlpuler dlrecLemenL des ocLeLs. Ln
effeL, LouLes les donnees lnformaLlques sonL represenLees avec des ocLeLs. nous allons examlner
Lrols Lypes parLlcullers de flux d'enLree eL de sorLle :
les flux de caracLeres ,
les flux de donnees blnalres ,
les flux d'ob[eLs serlallses.
9.8. Les f|ux de caractres
Lorsque l'on parle de caractres en lnformaLlque, on esL obllge de parler de [eu de
caractres (cbotset) eL de codage de caractres (eocoJloq).
Le [eu de caractres (cbotset) esL la llsLe des symboles que l'on consldere comme eLanL des
caracLeres. Le codage (eocoJloq) esL la manlere donL les caracLeres sonL represenLes sous forme
d'ocLeLs. un [eu de caracLeres conLlenL des symboles vlslbles ou lmprlmables comme ceux qul
flgurenL sur voLre clavler. Mals ll conLlenL aussl des symboles lnvlslbles ou non lmprlmables comme le
caracLere sauL de llgne .
Lxemp|e. un des plus anclens [eux de caracLeres esL l'ASCll (Ametlcoo 5tooJotJ coJe fot lofotmotloo
lotetcbooqe) qul conLlenL 128 caracLeres lssus de l'alphabeL anglals. Chaque caracLere peuL Lre code
sur 7 blLs car 2
7
=128. Cn peuL donc coder un caracLere sur un ocLeL donL l'un des blLs n'esL pas uLlllse.
Ln memolre, !ava uLlllse le [eu de caracLeres unlCCuL qul vlse a posseder LouL caracLere de
n'lmporLe quel sysLeme d'ecrlLure dans le monde (plus de 109,000 caracLeres). L'encodage sous
124
forme d'ocLeLs le plus couranL des caracLeres unlCCuL esL deflnl dans la norme u1l-8 (uolvetsol
1toosfotmotloo lotmot).
Lorsque l'on ecrlL des caracLeres dans un flux de sorLle, ll fauL cholslr un [eu de caracLeres eL son
codage. uLlllser unlCCuL eL u1l-8 esL en general sufflsanL. Lorsque l'on llL des caracLeres dans un
flux, ll esL necessalre de connaiLre le [eu de caracLeres uLlllse eL son codage. 1anL que l'on resLe
unlCCuL eL u1l-8, ll n'y a rlen a falre car !ava esL de[a conflgure pour cela. Sl l'on dolL llre un flchler
code dlfferemmenL, ll fauL consulLer la documenLaLlon des classes de flux de caracLeres.
Sl l'on se Lrompe de [eu de caracLeres eL d'encodage en lecLure, des erreurs de
decodage peuvenL apparaiLre. Cn le consLaLe parfols sur des pages Web ou dans les
emalls. ll se peuL, par exemple, que voLre navlgaLeur solL conflgure pour accepLer un
cerLaln [eu eL un cerLaln codage eL que la page que vous vlslonnez solL dans un auLre
[eu ou un auLre codage.
9.8.1. Lcr|re dans un f|ux de caractres
our ecrlre dans un flux de caracLeres, on encapsule un flux de sorLle d'ocLeLs dans un ob[eL qul salL
coder les caracLeres en ocLeLs. La classe d'encapsulaLlon esL PrintWriter.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 PrintWriter. Cherchez la documenLaLlon de
PrintWriter, examlnez-la.
our creer un ob[eL PrintWriter a parLlr d'un flchler :
PrintWriter pw = new PrintWriter("data.txt") ;
uls on dlspose de la meLhode print() qul lmprlme son argumenL dans le flchler eL println()
qul falL la mme chose mals en ra[ouLanL un sauL a la llgne. LL pour flnlr la meLhode close()
fermera le PrintWriter eL Lous les flux de sorLles qul onL pu Lre ouverL.
Cn n'oublle pas que LouLes ces meLhodes peuvenL provoquer des erreurs qu'll fauL arrLer avec un
bloc try-catch. Ln reprenanL le mme schema qu'en 9.3, cela donnera :
PrintWriter pw = null ;
try {
pw = new PrintWriter("data.txt") ;
pw.print("abc ") ;
pw.println(12) ;
pw.println("x") ;
} catch (Exception e) {
e.printStackStrace() ;
} finally {
try {
pw.close() ;
} catch (Exception e) {}
}
Cela donnera dans le flchler data.txt :
123
abc 12
x
noLons que le PrintWriter esL bufferlse.
ALLenLlon ! Sl le flchler exlsLalL, ll esL deLrulL par l'lnsLrucLlon :
pw = new PrintWriter("data.txt") ;
eL sera recree par les lnsLrucLlons sulvanLes. Sl l'on deslre a[ouLer du LexLe au flchler data.txt
pluLL que de le deLrulre pour Lre recree, on uLlllsera la forme la plus generale :
FileWriter fw = new Filewriter("data.txt",true) ;
BufferedWriter bw = new BufferedWriter(fw) ;
PrintWriter pw = new PrintWriter(bw) ;
La premlere lnsLrucLlon cree le un flux de caracLeres sur le flchler data.txt. Le parameLre true
dlL qu'll ne fauL pas effacer le flchler s'll exlsLe mals a[ouLer les ordres d'ecrlLure en fln de flchler. La
deuxleme lnsLrucLlon bufferlse le FileWriter.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 FileWriter. Cherchez la documenLaLlon de FileWriter,
examlnez-la, en parLlculler ses consLrucLeurs.
9.8.2. L|re dans un f|ux de caractres
our llre des caracLeres, on encapsule un flux d'enLree d'ocLeLs dans un ob[eL qul salL decoder les
ocLeLs en caracLeres. La classe d'encapsulaLlon esL Scanner.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Scanner. Cherchez la documenLaLlon de Scanner,
examlnez-la.
our creer un ob[eL Scanner a parLlr d'un flchler :
FileReader fr = new FileReader("data.txt") ;
BufferedReader br = new BufferedReader(fr) ;
Scanner sc = new Scanner(br) ;
uls on va uLlllser les meLhodes next(), nextInt(), nextLine() eL en regle generale LouLes
les meLhodes de Scanner qul commence par next. LL nous fermerons le Scanner avec la meLhode
close(). 8len enLendu, LouLes ces meLhodes sonL suscepLlbles de declencher des excepLlons. uonc
nous allons encore uLlllser le mme schema a base de try-catch pour rellre le flchler data.txt
ecrlL plus hauL :
126
Scanner sc = null ;
String s = null ;
int i = 0 ;
String e = null ;
String l = null ;
try {
sc = new Scanner(new BufferedReader(new BufferedReader(fr))) ;
s = sc.next() ; // s = "abc"
i = sc.nextInt() ; // i = 12
e = sc.netLine() ; // e = ""
l = sc.nextLine() ; // l = "x
} catch (Exception e) {
e.printStackStrace() ;
} finally {
try {
sc.close() ;
} catch (Exception e) {}
}
9.8.3. A propos des f|ux de caractres
ll exlsLe dlfferenLes manleres d'emboiLer les classes permeLLanL des flux de caracLeres en enLree ou
en sorLle. Ce Lrop-pleln de posslblllLes peuL Lre peru comme un lnconvenlenL du sysLeme
d'enLrees-sorLles de !ava. CependanL, n'oubllez pas que Coogle ou un auLre moLeur de recherche esL
voLre aml.
CerLalnes classes sonL plus slmples que d'auLres. Alnsl, sl l'on deslre llre un flux de caracLeres
unlquemenL llgne par llgne, on uLlllsera la classe BufferedReader plus slmple que la pulssanLe
classe Scanner.
uans le cas ou le flux, en enLree ou en sorLle, correspond a un elemenL maLerlel (flchler sur dlsque,
carLe reseau, eLc.), on velllera a ce que le flux solL bufferlse. ll peuL Lre bufferlse au nlveau
caracLeres, comme dans nos dernlers exemples, ou blen au nlveau ocLeLs.
uans Lous les cas, ll esL posslble de speclfler le [eu de caracLeres eL son codage. Slnon, le codage par
defauL du sysLeme d'explolLaLlon esL uLlllse.
9.9. I|ux de donnes b|na|res
Lorsque l'on veuL sLocker des donnees de base (int, float, eLc.), ll esL posslble de les sLocker sous
une forme LexLuelle comme expllquer en secLlon 9.8. Mals ce n'esL pas le plus efflcace. 1ous les Lypes
de base onL une represenLaLlon blen plus compacLe eL blen plus efflcace que la represenLaLlon
LexLuelle, c'esL leur represenLaLlon blnalre en memolre.
Llre ou ecrlre des donnees en blnalre esL blen plus efflcace que de les llre ou ecrlre sous
forme LexLuelle. Ln effeL, !ava les possede de[a en memolre sous forme blnalre alors
que pour les Lransformer sous forme LexLuelle, ll y a beaucoup de Lravall a falre dans la
classe PrintWriter. ll en esL de mme en lecLure avec la classe Scanner.
!ava propose des classes qul englobenL des flux d'ocLeLs eL qul y ecrlvenL ou llsenL les
represenLaLlons blnalres des Lypes de bases. 8len enLendu, de Lels flchlers ne pourronL Lre relus
qu'avec des programmes !ava.
127
Ces deux classes s'appellenL :
DataOutputStream pour ecrlre les represenLaLlons blnalres ,
DataInputStream pour rellre les represenLaLlons blnalres.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 DataOutputStream. Cherchez la documenLaLlon de
DataOutputStream, examlnez-la, en parLlculler ses consLrucLeurs.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 DataInputStream. Cherchez la documenLaLlon de
DataInputStream, examlnez-la, en parLlculler ses consLrucLeurs.
9.9.1. Lcr|re des donnes b|na|res
volcl un exemple de programme d'ecrlLure de donnees blnalres dans un flchler. nous devons meLLre
un bloc try-catch a cause des dlfferenLes excepLlons qul peuvenL Lre levees, volr la
documenLaLlon de DataOutputStream :
DataOutputStream dos = null ;
try {
dos = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("data.bin"))) ;
dos.writeInt(123) ;
dos.writeLong(234L) ;
dos.writeString("abc") ;
dos.writeFloat(12.3f) ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
try {
dos.close() ;
} catch (Exception e) {}
}
Le conLenu du flchler conLlenL les represenLaLlons blnalres des donnees. ll esL donc llllslble avec un
edlLeur.
9.9.2. L|re des donnes b|na|res
volcl un exemple de programme de lecLure de donnees blnalres dans un flchler. nous allons rellre les
donnees que nous y avons lnscrlLes dans la secLlon precedenLe. nous devons meLLre ces lnsLrucLlons
dans un bloc try-catch a cause des dlfferenLes excepLlons qul peuvenL Lre levees, volr la
documenLaLlon de DataInputStream :
128
DataInputStream dia = null ;
try {
dis = new DataOutputStream(
new BufferedInputStream(
new FileInputStream("data.bin"))) ;
int i = dis.readInt() ;
long l = dis.readLong() ;
String s = dis.readString() ;
float f = dis.readFloat() ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
try {
dis.close() ;
} catch (EXceptione) {}
}
9.10. I|ux d'ob[ets sr|a||ss (hors programme)
ue mme qu'll esL posslble d'ecrlre la represenLaLlon blnalre des donnees de base (les donnees
scalalres) dans un flux d'ocLeLs ll esL egalemenL posslble d'ecrlre la represenLaLlon blnalre d'un ob[eL.
ll n'esL nul besoln de connaiLre la represenLaLlon blnalre d'un ob[eL LouL comme ll n'eLalL nul besoln
de connaiLre la represenLaLlon blnalre d'une donnee de base.
Lorsque !ava calcule la reprsentat|on b|na|re d'un ob[eL, on dlL que !ava sr|a||se
l'ob[eL. C'esL le processus de sr|a||sat|on.
Lors du processus de serlallsaLlon d'un ob[eL, Lous les ob[eLs references par ses aLLrlbuLs sonL
egalemenL serlallses en mme Lemps que lul. LL blen enLendu, les ob[eLs references a parLlr des
aLLrlbuLs seronL aussl serlallses eL alnsl de sulLe. uonc sl une sLrucLure complexe esL serlallsee, une
ArrayList par exemple, Lous les elemenLs qu'elle conLlenL seronL serlallses avec elles.
!ava possede deux classes permeLLanL d'englober des flux d'ocLeLs pour en falre des flux d'ob[eLs
serlallses. Ce sonL :
ObjectOutputStream pour ecrlre les represenLaLlons blnalres d'ob[eLs ,
ObjectInputStream pour rellre les represenLaLlons blnalres d'ob[eLs.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 ObjectOutputStream. Cherchez la documenLaLlon de
ObjectOutputStream, examlnez-la, en parLlculler ses consLrucLeurs.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 ObjectInputStream. Cherchez la documenLaLlon de
ObjectInputStream, examlnez-la, en parLlculler ses consLrucLeurs.
129
1ous les ob[eLs ne sonL pas sr|a||sab|es.
Alnsl un ob[eL de Lype FileOutputStream n'esL pas serlallsable. Ln regle generale, LouL ob[eL qul
reference quelque chose a l'exLerleur de !ava n'esL pas serlallsable. Ln effeL, ll pourralL Lre
sauvegarder dans un flchler mals lorsqu'll s'aglra de le rellre, peuL-Lre que l'ob[eL exLerleur ne sera
plus la. ue mme, un ob[eL relaLlf a l'execuLlon parLlcullere d'un programme comme un processus
leger (une Thread que nous verrons plus Lard) n'esL pas serlallsable. 1echnlquemenL, les ob[eLs
serlallsables sonL des donnees pures de !ava.
Lorsque le programmeur declde qu'une classe esL serlallsable, ll declare que ceLLe
classe lmplemenLe l'lnLerface Serializable du package java.io.
Le programmeur peuL blen sr se Lromper. CeLLe lnLerface ne conLlenL rlen, ll ne s'aglL en falL qye
d'une lndlcaLlon pour le compllaLeur.
La classe de l'ob[eL serlallsable devra conLenlr un numero de serle ou de verslon :
public static final long serialVersionUID = 20110618L ;
Ln effeL, une classe peuL evoluer. Sl un ob[eL esL serlallse avec une verslon donnee d'une classe, ll ne
peuL Lre relu qu'avec la mme verslon de la classe. Cela suppose que le programmeur change le
numero de verslon chaque fols qu'll modlfle la classe. Alnsl, le compllaLeur peuL Lre vlgllanL.
9.10.1. Une c|asse sr|a||sab|e
volcl un exemple de classe serlallsable :
import java.io.* ;
public class Person
implements Serializable
{
public static final long serialVersionUID = 20110618L ;
private String firstName ;
private String lastName ;
public Person(String firstName, String lastName)
{
this.firstName = firstName ;
this.lastName = lastName ;
}
}
9.10.2. Lcr|ture d'un ob[et sr|a||s
our ecrlre un ob[eL serlallse, ll fauL dlsposer d'un ob[eL serlallsable. nous creons un ob[eL de la
classe erson cl-dessus :
Person person = new Person("Arthur","Pendragon") ;
130
uls nous allons uLlllser noLre bloc try-catch comme d'hablLude eL nous allons uLlllser la meLhode
writeObject de la classe ObjectOutputStream :
ObjectOutputStream oos = null ;
try {
oos = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream("data.bin"))) ;
oos.writeObject(person) ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
try {
oos.close() ;
} catch (Exception e) {}
}
9.10.3. Lecture d'un ob[et sr|a||s
our llre un ob[eL serlallse, ll fauL blen sr un ObjectInputStream qul conLlenL ceL ob[eL eL ll fauL
que le programme qul llL ceL ob[eL connalsse la classe de l'ob[eL. nous allons rellre l'ob[eL Person
sauve dans le flchler data.bin cree cl-dessus :
ObjectInputSTream ois = null ;
Person person = null ;
try {
ois = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("data.bin"))) ;
person = (Person)ois.readObject() ;
} catch (Exception e) {
e.printStackTrace() ;
} finally {
try {
ois.close() ;
} catch (Exception e) {}
}
L'ob[eL esL relu grce a la meLhode readObject(). C'esL une meLhode generlque qul va
foncLlonner pour Lous les Lypes d'ob[eLs eL son resulLaL esL de Lype Object qul esL le Lype le plus
general de !ava. Cr, c'esL un ob[eL de Lype Person. ll fauL le dlre au programme en effecLuanL ce
que l'on appelle un LransLypage ou cast. Sl l'on salL qu'un ob[eL p de Lype Object esL en falL une
Person, on obLlenL le mme ob[eL de Lype mals de Lype Person grce a l'expresslon :
(Person)p
C'esL ce que nous avons falL dans le programme avec la llgne en gras.
131
9.10.4. rob|mes avec |es f|ux d'ob[ets sr|a||ss
ll exlsLe dlfferenLs problemes relaLlfs aux flux d'ob[eLs serlallses.
Alnsl, ll ne fauL pas ecrlre plusleurs fols le mme ob[eL, mme apres modlflcaLlon, car !ava gere cela
avec un sysLeme de cache assez compllque.
CerLalns cas peuvenL poser probleme sl l'on sauve deux ob[eLs qul onL des aLLrlbuLs en commun :
Sl l'on sauvegarde l'ob[eL A eL l'ob[eL B pulsqu'on essale de les rellre, on va obLenlr :
C'esL a dlre que l'ob[eL C qul eLalL commun se reLrouve dupllque. Sl l'on veuL evlLer cela, ll fauL creer
un ob[eL Z qul a A eL B comme aLLrlbuLs :
Ln sauvegardanL Z pluLL que A eL B separemenL, cela resoudra le probleme. Ln recuperanL Z dans le
flchler, on re-obLlendra le graphe cl-dessus.
Ln regle generale, sl l'on veuL evlLer les problemes, ll esL consellle de ne sauver qu'un seul ob[eL par
flchler.
132
9.11. D'autres f|ux.
ll exlsLe beaucoup d'auLres Lypes de flux qul sonL solL fournls avec !ava solL dlsponlbles sur lnLerneL.
Cn peuL clLer par exemple :
GZipInputSTream eL GZipOutputStream pour la compresslon de flux d'ocLeLs.
SequenceInputStream pour la concaLenaLlon de flux d'ocLeLs.
AudioInputStream pour rellre les flchlers audlo.
Ln examlnanL les classes de !ava, vous en Lrouverez blen d'auLres. Ln parLlculler, sl vous avez un
Lravall a falre avec des flux d'ocLeLs, n'heslLez pas a aller sur le Web pour y rechercher ce donL vous
avez besoln. Cela exlsLe sremenL.
133
10. Comp|ments |nd|spensab|es
uans ceLLe secLlon, nous allons expllclLer quelques complemenLs, en parLlculler des choses qul n'onL
pas encore eLe vue allleurs.
10.1. Le transtypage (cast)
!ava esL un langage Lype. Les donnees onL des Lypes, les varlables aussl. Cn dlsLlngue les types
pr|m|t|fs ou scalalres (boolean, byte, char, short, int, long, float, double) eL les types
rfrences. Cn a vu en secLlon 7.6 Le polymorphlsme qu'un ob[eL de Lype reference pouvalL avolr
plusleurs Lypes. ll esL parfols posslble eL necessalre de converLlr des donnees d'un Lype en donnees
d'un auLre Lype. Cela s'appelle le transtypage. Cn dlsLlngue le LransLypage de Lypes prlmlLlfs de celul
des Lypes references.
uans le cas des LransLypages de Lypes prlmlLlfs, on peuL LransLyper d'un Lype vers un Lype de rang
plus eleve dans la hlerarchle sulvanLe :
double
float
long
int
short
byte
Cn peuL alnsl ecrlre :
int i = 3 ;
float f = (float) I ;
Sl l'on essale de LransLyper un Lype vers un Lype de rang plus falble, le resulLaL esL lmprevlslble.
uans le cas des LransLypage de Lypes references, on falL appel au polymorphlsme lul-mme enLraine
par l'herlLage. Supposons une classe Animal eL un sous-classe Chat. un ob[eL de Lype Chat esL
donc aussl de Lype Animal. Cn peuL donc ecrlre :
Char chat = new Chat() ;
Animal animal = (Animal)chat ;
134
L'lnverse n'esL pas vral. 1ouL anlmal n'esL pas un chaL eL ll esL a prlorl lmposslble de LransLyper une
reference sur un ob[eL de Lype Animal en une reference sur un ob[eL de Lype Chat. Sl l'on veuL
LransLyper une reference de Lype Animal en une reference de Lype Chat, cela se verlfle a
l'execuLlon eL cela peuL provoquer une excepLlon. lmaglnons l'lnsLrucLlon :
chat = (Chat) animal ;
sl animal conLlenL une reference sur un Chat, alors LouL va blen eL la reference se
Lrouvera dans la varlable chat ,
mals sl animal conLlenL une reference sur un auLre anlmal, un Chien par exemple, !ava
levera une excepLlon.
noLons que !ava effecLue pour vous le LransLypage s'll n'esL pas expllclLemenL ecrlL comme dans les
exemples cl-dessous :
float f = 3 ;
Animal animal = chat ;
10.2. L'|nstruct|on break
L'lnsLrucLlon break permeL d'lnLerrompre l'execuLlon d'une sLrucLure de conLrle eL
de passer a la sulLe.
Lxemp|e. L'lnsLrucLlon switch :
switch (n)
{
case 0 :
break ;
case 1 :
break ;
case 2 :
break ;
}
C'esL l'lnsLrucLlon break qul permeL de sorLlr de l'lnsLrucLlon switch. L'oubll de l'lnsLrucLlon
break dans une lnsLrucLlon switch esL une excellenLe source de bug.
Lxemp|e. arcourlr une Lable D de Data [usqu'a renconLrer null.
for (Data d : D) {
if (d == null)
break ;
}
133
10.3. C|asses |mbr|ques
ll esL posslble de deflnlr une classe a l'lnLerleur d'une auLre classe.
un programme esL normalemenL compose de classes. Chaque classe esL deflnle dans son propre
flchler. ll esL neanmolns posslble de deflnlr une classe a l'lnLerleur d'une auLre classe pour un usage
generalemenL local. Cn parle alors de c|asses |mbr|ques (looet closs).
Lxemp|e.
public class Registry
{
public class Person
{
}
private ArrayList<Person> registry ;
}
Sl la classe lmbrlquee, lcl Person, esL declaree public, elle esL uLlllsable depuls l'exLerleur de la
classe englobanLe. uepuls l'exLerleur de la classe englobanLe, le nom de la classe lmbrlquee dolL Lre
preflxe par le nom de la classe englobanLe. uans noLre cas, cela donne Registry.Person.
10.4. C|asses anonymes
ll esL posslble de declarer une classe sans lul donner de nom.
Cn parle alors de c|asse anonyme. Cecl n'esL lnLeressanL que sl l'on deslre ne creer qu'un seul ob[eL
de ceLLe classe. Cn dc|are |a c|asse et on |'|nstanc|e en mme temps. Cn cholslL une lnLerface eL on
l'lnsLancle en fournlssanL les lmplemenLaLlons des meLhodes declarees.
Lxemp|e. Avec l'lnLerface ActionListener.
ActionListerner al = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
mainWindow.close() ;
}
} ;
lcl, ActionListener esL une lnLerface. nous creons une classe anonyme qul lmplemenLe ceLLe
lnLerface en meLLanL en ouvre la meLhode actionPerformed. LL nous creons un ob[eL avec
l'lnsLrucLlon new.
136
10.S. Les co||ect|ons
Les co||ect|ons de Iava sonL des classes de sLrucLures de donnees proposees par !ava.
une classe des collecLlons de !ava esL une sLrucLure de donnees qul regroupe un nombre varlable
d'ob[eLs. ll exlsLe dlfferenLes manleres de regrouper des ob[eLs selon l'usage que l'on compLe falre de
ceLLe collecLlon. Les collecLlons sonL aussl represenLees par des lnLerfaces qul deflnlssenL les vues
que l'on peuL avolr des ob[eLs collecLlons. Lnfln, les collecLlons sonL enfln represenLees par un
ensemble d'algorlLhmes qul permeLLenL de les manlpuler.
10.S.1. Itrat|on sur |es co||ect|ons
1ouLes les collecLlons supporLenL la boucle for generallsee. Sl D esL une collecLlon d'ob[eL de Lype
Data, on peuL parcourlr ceLLe collecLlon avec l'lnsLrucLlon :
for (Data d : D) {
)
1ouL comme les ArrayList, LouLes les classes de collecLlons supporLenL la creaLlon d'lLeraLeurs qul
permeLLenL egalemenL de les parcourlr. Sl u esL une collecLlon d'ob[eL de Lype uaLa, on peuL uLlllser
un lLeraLeur pour le parcourlr.
10.S.2. Les |nterfaces
Les dlfferenLes lnLerfaces des collecLlons :
L'lnLerface Collection esL la raclne. Llle conLlenL ce qul esL commun a LouLes les collecLlons.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Collection. Cherchez la documenLaLlon de Collection,
examlnez-la.
137
L'lnLerface Set represenLe un ensemble flnl d'ob[eLs ou un mme ob[eL ne peuL apparaiLre deux fols.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Set. Cherchez la documenLaLlon de Set, examlnez-la.
L'lnLerface SortedSet represenLe un ensemble flnl d'ob[eLs ou un mme ob[eL ne peuL pas
apparaiLre deux fols. ll y a une foncLlon d'ordre a fournlr sur les elemenLs de l'ensemble. Ln mme
Lemps que les elemenLs sonL lnseres dans l'ensemble, lls sonL malnLenus en ordre crolssanL.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 SortedSet. Cherchez la documenLaLlon de SortedSet,
examlnez-la.
L'lnLerface List represenLe une llsLe d'ob[eLs. Les elemenLs de la llsLe onL aussl une poslLlon dans la
llsLe maLerlallsee par un lndex. ll esL posslble d'lnserer un elemenL dans une llsLe.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 List. Cherchez la documenLaLlon de List, examlnez-la.
L'lnLerface Queue represenLe une queue d'ob[eLs. C'esL une flle d'aLLenLe.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Queue. Cherchez la documenLaLlon de Queue, examlnez-la.
L'lnLerface Map represenLe une Lable d'assoclaLlon cle - valeur . Cn parle parfols de Lable de
hashage.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Map. Cherchez la documenLaLlon de Map, examlnez-la.
L'lnLerface SortedMap represenLe une Lable d'assoclaLlon cle - valeur . Cn parle parfols de
Lable de hashage. ll y a une foncLlon d'ordre sur les cles a fournlr. Les elemenLs sonL malnLenus en
ordre ascendanL des cles. C'esL LyplquemenL un annualre ou un reperLolre Lelephonlque.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 SortedMap. Cherchez la documenLaLlon de SortedMap,
examlnez-la.
138
10.S.3. Les c|asses |mp|mentant |es |nterfaces
Les co||ect|ons de Iava proposenL un cerLaln nombre de classes concreLes
lmplemenLanL les lnLerfaces de la secLlon precedenLe.
ll y a des lmplemenLaLlons qul supporLenL les acces concurrenLs par des processus legers (tbteoJ).
10.S.4. uand ut|||ser |es tab|es ?
Cn uLlllse les Lables lorsque l'on deslre que l'acces a un elemenL se fasse en Lemps consLanL ou
presque. CependanL l'lnserLlon ou l'effacemenL d'un elemenL esL couLeuse. Sl [e deslre lnserer un
elemenL enLre les elemenLs e1 eL e2 du Lableau cl-dessus, ll fauL que ['agrandlsse le Lableau eL que
les elemenLs enLre e2 eL e4 solenL recoples vers le bas. La classe des Lables esL la classe
ArrayList.
10.S.S. uand ut|||ser |es ||stes ?
uans le cas des llsLes, l'acces a un elemenL se falL en Lemps llnealre. Ln revanche, l'lnserLlon ou
l'enlevemenL d'un elemenL esL plus faclle. uonc sl l'on dolL souvenL lnserer ou supprlmer des
elemenLs, ll vauL mleux uLlllser des llsLes. La classe des llsLes esL LinkedList.
10.S.6. Cho|s|r sa structure de donnes
LinkedList eL ArrayList sonL deux classes des collecLlons de !ava. Cn cholslra l'une ou l'auLre
en foncLlon des operaLlons prevues sur la sLrucLure de donnees comme expllquee dans les deux
secLlons precedenLes.
139
Mals ce que nous venons de dlre sur les llsLes esL valable pour LouLes les sLrucLures de donnees.
AvanL d'en cholslr une, ll convlenL de llre aLLenLlvemenL sa documenLaLlon :
Cuel esL le Lemps d'acces a un elemenL ?
Cuel esL le Lemps d'lnserLlon d'un elemenL ?
Cuel esL le Lemps de suppresslon d'un elemenL ?
10.S.7. Les a|gor|thmes
Les co||ect|ons de Iava proposenL un cerLaln nombre d'algorlLhmes qul s'appllquenL
aux collecLlons.
La classe Collections conLlenL un cerLaln nombre de meLhodes de classes (static) meLLanL en
ouvre des algorlLhmes sur les collecLlons.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Collections. Cherchez la documenLaLlon de
Collections, examlnez les meLhodes qul s'appllquenL aux collecLlons.
141
11. Constru|re son InM
(hors programme)
Les lnLerfaces homme-machlne (lPM) permeLLenL aux appllcaLlons eL aux uLlllsaLeurs d'lnLeraglr.
Llles prennenL la forme de fenLres conLenanL des wlJqets : bouLons, menus, champs d'enLree, zone
de dessln, eLc. Les auLres noms des InM sonL les lnLerfaces uLlllsaLeurs (uset lotetfoce, UI), les
lnLerfaces graphlques (Ctopblcol uset lotetfoce, GUI), les lnLerfaces personne-machlne, eLc.
L'ensemble des ouLlls qul permeLLenL de programmer une lnLerface uLlllsaLeur esL appele un
toolklt (boiLe a ouLlls) graphlque. !ava propose plusleurs toolklts graphlques :
AW1 (Absttoct wloJow 1oolklt), le premler toolklt !ava , ll esL malnLenanL depasse ,
SW1 (5tooJotJ wlJqet 1oolklt) esL lle a l'envlronnemenL de developpemenL Lcllpse ,
eL SWlnC, le toolklt acLuel de !ava.
uans le cadre de ce cours, nous uLlllsons le toolklt graphlque SWlnC.
Les wlJqets (wloJow CoJqet) sonL appeles des composanLs (compooeots) dans SWlnC.
11.1. rogrammer une InM
uans la pluparL des cas, programmer une lPM revlenL a programmer une fenLre graphlque :
ll fauL consLrulre la fenLre eL Lous les composanLs (compooeots) qu'elle conLlenL. 1ouL esL
ob[eL au sens de !ava.
ll fauL ensulLe programmer les comporLemenLs des composanLs en foncLlon des acLlons de
l'uLlllsaLeur. ar exemple : cllcs de sourls, mouvemenLs de sourls, frappes sur le clavler.
uans ce cours, nous allons sulvre le plan sulvanL :
Lxpllquer commenL sonL organlsees les lnLerfaces. Ln parLlculler, la hlerarchle des ob[eLs, l.e.
l'arbre d'lnsLanclaLlon, qul composenL une lnLerface eL commenL lls sonL auLomaLlquemenL
agences dans la fenLre.
142
Lxpllquer le foncLlonnemenL de SWlnC eL en parLlculler, commenL sonL reallsees les
reponses de l'lnLerface aux acLlons de l'uLlllsaLeur eL commenL le programmeur deflnlL ces
reacLlons.
1ouL au long des chaplLres concernanL les lPM, nous allons lmposer une meLhodologle
qul, sl elle n'esL pas la plus efflcace, esL la plus slmple. Cn peuL praLlquer auLremenL.
CependanL, elle apporLe une praLlque sLandardlsee eL faclle a sulvre.
11.2. La construct|on de |'|nterface, |es panneaux et |es |ayouts
une fenLre graphlque esL un ob[eL graphlque de la classe JFrame. une fenLre peuL avolr une
barre de menu de Lype JMenuBar. L'lnLerleur de la fenLre esL un panneau graphlque de Lype
JPanel. ll y a blen d'auLres subLlllLes que nous ne verrons pas lcl.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 JFrame. Cherchez la documenLaLlon de JFrame.
Cn recommande de creer une classe pour la fenLre graphlque de voLre appllcaLlon
mals egalemenL une classe pour chaque composanL ma[eur de l'lnLerface.
11.3. Constru|re une fentre
volcl la classe pour une fenLre que l'on appelle DrawingApp, elle esL dans le package ui. nous
lmporLons le package java.swing.* qul conLlenL l'essenLlel des dlfferenLes classes graphlques :
package ui ;
import javax.swing.* ;
public class DrawingApp extends JFrame
{
public DrawingApp()
{
super("Drawing Application") ; // Window title
// Window menu bar creation
// Window content creation
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
pack() ; // This sets components sizes, positions
setVisible(true) ; // And the great show !
}
}
143
Cn volL :
L'appel au consLrucLeur de JFrame :
super("Drawing Application") ;
cree la fenLre prlnclpale LouL en fournlssanL son nom "Drawing Application".
uls nous avons lalsse :
o une place pour y meLLre le code qul creera la barre de menu ,
o eL une auLre place qul creera le conLenu de la fenLre, c'esL-a-dlre l'ensemble des
composanLs qul flgureronL dans la fenLre.
L 'lnsLrucLlon :
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ,
falL en sorLe que l'appllcaLlon !ava se Lermlne sl vous Luez la fenLre.
L'lnsLrucLlon :
pack() ;
prend les composanLs, les meL a la bonne Lallle eL les poslLlonne sur l'ecran. our cela, on
uLlllse la noLlon de loyoot que nous allons volr plus loln.
LL pour flnlr, l'lnsLrucLlon :
setVisible(true) ;
rend la fenLre vlslble.
11.4. u| do|t conna|tre qu| ?
nous allons creer des composanLs qul flgureronL dans la fenLre eL nous devrons programmer ces
composanLs. ar exemple, le menu Quit devra envoyer un message a la fenLre pour qu'elle se
ferme. our cela, nous decldons que tous |es composants conna|tront |a fentre, c'esL-a-dlre que
Lous les composanLs auronL un aLLrlbuL qul sera la fenLre prlnclpale.
our cela, nous donnerons au consLrucLeur de chaque composanL une reference sur la
fenLre prlnclpale qu'll gardera dans un de ses aLLrlbuLs.
Mals seuls les composanLs qul dolvenL reaglr aux acLlons de l'uLlllsaLeur devronL garder une
reference sur la fenLre prlnclpale dans un de leurs aLLrlbuLs. Cela slgnlfle que toutes |es ract|ons
aux act|ons de |'ut|||sateur seront demandes |a fentre pr|nc|pa|e.
ar allleurs, quand on demandera une reacLlon a la fenLre, celle-cl demandera des acLlons a ses
sous-composanLs qul demanderonL eux-mmes a leurs sous-composanLs eL alnsl de sulLe. uans ceL
opLlque, nous allons sysLemaLlquemenL falre en sorLe que chaque composanL connaiL ses sous-
composanLs, c'esL-a-dlre qu'elle les garde dans ses aLLrlbuLs.
Chaque composanL qul conLlenL d'auLres composanLs gardera des references sur ces
dernlers. Cela peuL Lre uLlle pour aglr sur eux, par exemple pour acLlver ou desacLlver
un bouLon.
144
11.S. Une barre de menu
volcl une barre de menu :
uans la barre de menu de Lype JMenuBar, nous aurons des menus de Lype JMenu. Chaque JMenu
conLlendra des lLems de menu de Lype JMenuItem.
11.6. Un |tem de menu
volcl l'lLem de menu QuiMenuItem qul correspond au menu u|t. Celul-cl n'esL pas encore
programme pour repondre aux acLlons de l'uLlllsaLeur :
package ui ;
import javax.swing.* ;
public final class QuitMenuItem extends JMenuItem
{
private final DrawingApp drawingApp ;
public QuitMenuItem(DrawingApp drawingApp)
{
super("Quit") ;
this.drawingApp = drawingApp ;
}
}
Cn volL que le consLrucLeur de ceLLe classe prend en argumenL la fenLre prlnclpale qu'll sLocke dans
un de ses aLLrlbuLs. L'appel au consLrucLeur de JMenuItem :
super("Quit") ;
cree l'lLem de menu LouL en flxanL son nom.
143
N.8. ll esL posslble de meLLre des lmages dans les lLems de menus. ll esL egalemenL posslble
d'assocler des sequences clavler a des lLems de menus.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java Menu tutorial. Cherchez un LuLorlel sur les menus.
1el que programme cl-dessus l'lLem de menu ne declenche aucune acLlon lorsque l'on cllque dessus.
nous ne donnons qu'un seule exemple d'lLem de menu.
11.7. Le menu
un menu de Lype JMenu esL desLlne a Lre place dans la barre de menu de Lype JMenuBar. Le
menu ne declenche a prlorl aucune acLlon car ce sonL les lLems de menu qul declenchenL les acLlons.
ll n'esL donc pas necessalre qu'lls connalssenL la fenLre. La fenLre prlnclpale, Lransmlse en
argumenL du consLrucLeur, sera slmplemenL re-donne au consLrucLeur des lLems de menu. 8len
enLendu, on gardera des references sur les sous-composanLs qul sonL des JMenuItem.
package ui ;
import javax.swing.* ;
public final class FileMenu extends JMenu
{
private final QuitMenuItem quitMenuItem ;
public FileMenu(DrawingApp drawingApp)
{
super("File") ;
add(quitMenuItem = new QuitMenuItem(drawingApp)) ;
}
}
Cecl esL LyplquemenL une classe de menu. Cn Lrouve d'abord les aLLrlbuLs desLlnes a conLenlr des
references sur les lLems de menu. uls le consLrucLeur qul appelle le consLrucLeur de JMenu en lul
donnanL le nom de menu. LL les lnsLrucLlons qul a[ouLenL les lLems de menu. noLons que
l'lnsLrucLlon :
add(quitMenuItem = new QuitMenuItem(drawingApp)) ;
esL equlvalenLe a :
quitMenuItem = new QuitMenuItem(drawingApp) ;
add(quitMenuItem) ;
Ln effeL, une affecLaLlon esL aussl une expresslon qul a pour valeur la valeur affecLee.
nous ne donnons qu'un seul exemple de menu.
146
11.8. La barre de menu
La barre de menu de Lype JMenuBar esL comme le menu, elle ne declenche aucune acLlon. Llle
n'aura pas besoln de garder la fenLre prlnclpale dans un aLLrlbuL. Ln revanche, elle la donnera aux
consLrucLeurs des menus qu'elle conLlenL. Cn obLlenL cecl :
package ui ;
import javax.swing.* ;
public final class DrawingMenuBar extends JMenuBar
{
private FileMenu fileMenu ;
public DrawingMenuBar(DrawingApp drawingApp)
{
super() ;
add(fileMenu = new FileMenu(drawingApp) ;
}
}
uans ceLLe classe, egalemenL Lyplque, on volL d'abord les aLLrlbuLs qul conLlendronL les menus, de
Lype JMenu, correspondanL aux sous-composanLs de la barre de menu. uls nous avons le
consLrucLeur qul commence par l'appel au consLrucLeur de JMenuBar eL se poursulL par l'a[ouL des
dlfferenLs menus que l'on sLockera dans les aLLrlbuLs au fur eL a mesure de leurs creaLlons.
11.9. Crer |a barre de menu
A presenL, nous pouvons creer la barre de menu dans la fenLre prlnclpale. Cn n'oubllera pas de la
garder dans un aLLrlbuL de la fenLre :
147
package ui ;
import javax.swing.* ;
public class DrawingApp extends JFrame
{
private final DrawingMenuBar drawingMenuBar ;
public DrawingApp()
{
super("Drawing Application") ; // Window title
drawingMenuBar = new DrawingMenuBar(drawingApp) ;
setJMenuBar(drawingMenuBar) ;
// Window content creation
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
pack() ; // This sets components sizes, positions
setVisible(true) ; // And the great show !
}
}
8len enLendu, les lnsLrucLlons :
drawingMenuBar = new DrawingMenuBar(drawingApp) ;
setJMenuBar(drawingMenuBar) ;
peuvenL s'ecrlre :
setJMenuBar(drawingMenuBar = new DrawingMenuBar(drawingApp)) ;
pulsque l'affecLaLlon esL une expresslon qul a pour valeur la valeur affecLee.
11.10. Le programme qu| cre |a fentre
Le programme qul cree la fenLre sera mls dans un package main :
package main ;
import ui.* ;
public class Main
{
public static void main(String[] args)
{
new DrawingApp() ;
}
}
Comme speclfle dans la classe DrawingApp, l'appllcaLlon se Lermlnera quand le fenLre sera
deLrulLe. noLons que nous avons d lmporLer le package ui.
148
Sl nous execuLons ce programme, nous obLenons cecl
6
:
La fenLre esL Lres peLlLe parce que la fenLre ne conLlenL rlen. ll n'y a que le menu. uonc
l'lnsLrucLlon pack() de la classe DrawingApp redulL la Lallle au mlnlmum. Cn peuL verlfler que les
menus sonL la mals lls ne sonL pas encore programmes donc un cllc sur un menu ne provoquera rlen.
nous avons cree une classe par ob[eL graphlque eL chacun de ses ob[eLs possede une
reference sur la fenLre. Cela faclllLera la programmaLlon de l'lnLerface, c'esL-a-dlre ses
reacLlons aux acLlons de l'uLlllsaLeur.
ll esL blen enLendu posslble de programmer auLremenL. CependanL, ceLLe dlsclpllne de
programmaLlon Lres unlforme vous permeL d'avolr un code plus clalr eL vous permeL un debugagge
plus faclle.
11.11. Le contenu de |a fentre
Le conLenu de la fenLre esL un ob[eL panneau de Lype JPanel. un JPanel peuL conLenlr d'auLres
composanLs Lels que des bouLons, des champs d'enLree, eLc. ll peuL aussl conLenlr d'auLres JPanel.
Le conLenu de la fenLre esL donc une hlerarchle de JPanel appelee l'arbre d'|nstanc|at|on. un
JPanel peuL egalemenL Lre uLlllse pour desslner, nous verrons commenL.
L'agencemenL des sous-composanLs d'un JPanel, c'esL-a-dlre leur poslLlons eL leurs Lallles, esL
deLermlnee par un ob[eL de Lype Layout qul esL assocle au JPanel. Les sous-composanLs d'un
JPanel apparalssenL a l'lnLerleur du JPanel.
Le programmeur ne gere pas lul-mme la Lallle eL la poslLlon des composanLs, ll confle
ceLLe Lche a un ob[eL Layout.
ll exlsLe dlfferenLs Lypes de loyoots permeLLanL des agencemenLs dlfferenLs.
11.12. Les composants SWING
SWlnC propose de nombreux composanLs.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java a visual guide to SWING components.
L'usage des composanLs n'esL pas forcemenL slmple mals rappelez-vous que voLre navlgaLeur prefere
eL voLre moLeur de recherche prefere sonL vos amls. Alnsl, sl vous deslrez uLlllser le composanL qul
permeL de cholslr une couleur, le JColorChooser, ne pas heslLer a enLrer dans voLre moLeur de
recherche :
JAVA JColorChooser tutorial
6
Cecl esL une fenLre du sysLeme CS. Mals sous Wlndows ou sous Llnux, vous obLlendrez une fenLre aussl
peLlLe que celle-cl.
149
11.13. Une pet|te app||cat|on
A parLlr de noLre fenLre prlnclpale DrawingApp, nous allons reallser une peLlLe appllcaLlon
permeLLanL d'edlLer des segmenLs sur une zone de dessln, de sauvegarder l'eLaL du dessln dans un
flchler LexLe eL de le recharger a parLlr du flchler LexLe lors d'une execuLlon fuLure. Ln SWlnC, une
zone de dessln eL un JPanel vlde comme nous le verrons.
our creer un segmenL, ll fauL cllquer avec le bouLon gauche, malnLenlr le bouLon appuye, deplacer
la sourls [usqu'a l'exLremlLe du segmenL eL relcher le bouLon de la sourls.
our effacer un segmenL, ll fauL le selecLlonner avec un double cllc eL appuyer sur le bouLon Lrase
Segment qul sera presenL dans l'lnLerface.
Les segmenLs peuvenL avolr des couleurs dlfferenLes.
11.14. ue| arrangement ?
L'arrangemenL des composanLs de l'lnLerface sera alnsl :
Le W|ndow ane| sera un JPanel. Ce sera celul qul sera le panneau prlnclpal de la fenLre. ll
conLlendra deux auLres panneaux : le Draw|ng ane| eL le 8uttons ane|.
Le Draw|ng ane| esL aussl un JPanel mals ll resLera vlde car ll sera uLlllse pour desslner.
Le 8uttons ane| esL un JPanel qul conLlendra le panneau Co|or Ind|cator, le bouLon Co|or
Chooser eL le bouLon Lrase Segment.
o Le Co|or Ind|cator esL slmplemenL un JPanel qul sera uLlllse pour desslner la
couleur cholsle pour les segmenLs.
o Le Co|or Chooser esL un bouLon, de Lype JButton, qul fera apparaiLre un
composanL qul permeL de cholslr la couleur des segmenLs.
o Le Lrase Segment esL un bouLon, de Lype JButton, qul permeL d'effacer un
segmenL comme expllque dans la secLlon precedenLe.
130
11.1S. Co|or Ind|cator
Le Co|or Ind|cator esL un slmple JPanel dans lequel on desslnera un carre Lemoln de la couleur
couranLe pour les segmenLs. La reference sur la fenLre prlnclpale servlra a reLrouver ceLLe couleur
quand ll faudra desslner le carre Lemoln. rogrammons ce Co|or Ind|cator sans aucun dessln pour
l'lnsLanL :
package ui ;
import javax.swing.* ;
public final class ColorIndicator extends JPanel
{
private final DrawingApp drawingApp ;
public ColorIndicator(DrawingApp drawingApp)
{
super() ;
this.drawingApp = drawingApp ;
}
}
11.16. Co|or Chooser
Le Co|or Chooser esL un bouLon de Lype JButton. ll ouvrlra une fenLre popop permeLLanL de
cholslr une nouvelle couleur.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 JButton. Lxamlnez la classe.
nous programmons le Co|or Chooser mals sans programmer la reacLlon lorsque l'uLlllsaLeur cllque
dessus. Le nom flguranL dans le bouLon dolL Lre donne dans le consLrucLeur de JButton :
package ui ;
import javax.swing.* ;
public final class ColorChooser extends JButton
{
private final DrawingApp drawingApp ;
public ColorChooser(DrawingApp drawingApp)
{
super("Choose color") ;
this.drawingApp = drawingApp ;
}
}
11.17. Lrase Segment
nous programmons Lrase Segment sans programmer la reacLlon lorsque l'uLlllsaLeur cllque dessus.
Le code esL Lres slmllalre a celul du Co|or Chooser :
131
package ui ;
import javax.swing.* ;
public final class EraseSegment extends JButton
{
private final DrawingApp drawingApp ;
public EraseSegment(DrawingApp drawingApp)
{
super("Erase segment") ;
this.drawingApp = drawingApp ;
}
}
11.18. 8uttons ane|
Le 8uttons ane| esL un slmple Iane| qul dolL conLenlr les Lrols composanLs que nous venons de
deflnlr. Les Lrols composanLs dolvenL Lre de mme Lallle, 1/3 de la Lallle du 8uttons ane|. nous
allons donc meLLre un loyoot sur noLre JPanel puls a[ouLer les Lrols sous-composanL. Le loyoot qul
nous lnLeresse esL le GridLayout qul meLs les sous-composanLs dans les cases d'une grllle. lcl,
nous prendrons une grllle de 1 llgnes eL 3 colonnes.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 GridLayout. Lxamlnez la classe.
Comme les loyoots exlsLalenL du Lemps d'AW1, lls sonL dans un package java.awt :
package ui ;
import java.awt.* ;
import javax.swing.* ;
public final class ButtonsPanel extends JPanel
{
private final ColorIndicator colorIndicator ;
private final ColorChooser colorChooser ;
private final EraseSegment eraseSegment ;
public ButtonsPanel(DrawingApp drawingApp)
{
super() ;
setLayout(new GridLayout(1,3)) ;
add(colorIndicator = new ColorIndicator(drawingApp)) ;
add(colorChooser = new ColorChooser(drawingApp)) ;
add(eraseSegment = new EraseSegment(drawingApp)) ;
}
}
132
11.19. Draw|ng ane|
La Draw|ng ane| esL un slmple JPanel sur lequel nous desslnerons. nous verrons commenL y
desslner plus Lard. Cn se conLenLe de meLLre sa couleur de fond en blanc, ce qul se falL par la
meLhode setBackground(Color.WHITE). WHITE esL une varlable de classe consLanLe de la
classe Color. lus lmporLanL esL le falL qu'une lnsLrucLlon pack() sera execuLee plus Lard dans la
fenLre prlnclpale. Celle-cl va LenLer de redulre au maxlmum les composanLs qul sonL conLenus dans
la fenLre. Cr, le Draw|ng ane| ne conLenanL rlen, sa Lallle mlnlmale esL 0x0. ll lmporLe de dlre au
sysLeme que la Lallle preferee du Draw|ng ane| esL 236x236. Alnsl, la meLhode pack() de la fenLre
prlnclpale essalera de mlnlmlser les composanLs LouL en essayanL de garder la Lallle 236x236 pour le
Draw|ng ane|. Cela donne :
package ui ;
import javax.swing.* ;
import java.awt.* ;
public class DrawingPanel extends JPanel
{
private final DrawingApp drawingApp ;
public DrawingPanel(DrawingApp drawingApp)
{
super() ;
this.drawingApp = drawingApp ;
setBackground(Color.WHITE) ;
setPreferredSize(new Dimension(256,256)) ;
}
}
La classe Dimension esL dans le package java.awt.
11.20. W|ndow ane|
La W|ndow ane| dolL conLenlr le Draw|ng ane| au dessus du 8uttons ane|. Cn ne peuL uLlllser le
GridLayout car ces deux composanLs auralenL la mme hauLeur. Ln revanche, le
BorderLayout semble LouL a falL convenlr.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 BorderLayout. Lxamlnez la classe.
133
Les composanLs d'un BorderLayout peuvenL Lre a[ouLes dans ses 3 parLles :
Cn peuL donc a[ouLer le Draw|ng ane| dans la zone CENTER eL le 8uttons ane| dans la zone
SOUTH. our a[ouLer un composanL avec le BorderLayout, on uLlllse une meLhode add avec le
deux parameLres. Le premler esL le composanL que l'on a[ouLe. Le deuxleme esL la poslLlon ou l'on
veuL l'a[ouLer : BorderLayout.CENTER, BorderLayout.NORTH, eLc.
Cela donne :
package ui ;
import javax.swing.* ;
import java.awt.* ;
public final class WindowPanel extends JPanel
{
private final DrawingPanel drawingPanel ;
private final ButtonsPanel buttonsPanel ;
public WindowPanel(DrawingApp drawingApp)
{
super() ;
setLayout(new BorderLayout()) ;
add(drawingPanel = new DrawingPanel(drawingPanel),
BorderLayout.CENTER) ;
add(buttonsPanel = new ButtonsPanel(drawingPanel),
BorderLayout.SOUTH) ;
}
}
134
11.21. La fentre pr|nc|pa|e
nous pouvons a presenL lnLrodulre le W|ndow ane| dans la fenLre prlnclpale :
package ui ;
import javax.swing.* ;
public final class DrawingApp extends JFrame
{
private final DrawingMenuBar drawingMenuBar ;
private final WindowPanel windowPanel ;
public DrawingApp()
{
super("Drawing application") ;
drawingMenuBar = new DrawingMenuBar(this) ;
setJMenuBar(drawingMenuBar) ;
windowPanel = new WindowPanel(this) ;
setContentPanel(windowPanel) ;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
pack() ;
setVisible(true) ;
}
}
11.22. Les |ayouts
ll exlsLe dlfferenLs Lypes de loyoots en !ava :
GridLayout. Ce loyoot dlspose les sous-composanLs sur les cases d'une grllle.
BorderLayout. Ce loyoot dlspose les sous-composanLs dans clnq zones.
CardLayout. Ce loyoot dlspose les sous-composanLs dans des ongleLs.
BoxLayout. Ce loyoot dlspose les sous-composanLs en llgne ou en colonne.
Ces quaLre precedenLs loyoots sonL en general sufflsanLs pour les dlsposlLlons les plus communes des
composanLs. ll exlsLe Lrols auLres loyoots un peu plus compllques a uLlllser :
SpringLayout : agencemenL avec des conLralnLes.
FlowLayout : allgnes de gauche a drolLe avec passage a la llgne.
GridBagLayout : grllle avec des conLralnLes, Lres flexlble mals Lres compllques.
Les dlfferenLs loyoots peuvenL Lre examlne en regardanL les classes qul lmplemenLenL l'lnLerface
LayoutManager.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 LayoutManager. Lxamlnez l'lnLerface eL les classes qul
lmplemenLe ceLLe lnLerface.
133
11.23. Conc|us|ons
nous avons consLrulL noLre lnLerface sans la programmer, c'esL-a-dlre sans programmer les reacLlons
aux acLlons de l'uLlllsaLeur.
nous avons adopLe les prlnclpes sulvanLs :
1ous les composanLs qul auronL a reaglr aux acLlons de l'uLlllsaLeur connalssenL, dans leurs
aLLrlbuLs, la fenLre prlnclpale.
Chaque composanL qul a des sous-composanLs possede des aLLrlbuLs qul sonL des references
sur ces sous-composanLs.
La Lallle eL la dlmenslon de chaque composanL sonL gerees par des loyoots qul sonL
poslLlonnes dans le composanL qul le conLlenL.
ll ne fauL pas gerer sol mme les Lallles eL les dlmenslons des composanLs. La seule chose que l'on
pulsse falre esL de deflnlr la Lallle mlnlmal ou la Lallle preferee des composanLs comme nous l'avons
falL en secLlon 11.19.
noLons comme nous l'avons dlL au debuL, que ceLLe meLhode pour consLrulre une lnLerface requlerL
plus de code mals qu'elle esL aussl plus clalre eL plus slmple a debugger.
137
12. Dess|ner avec son InM
(hors programme)
uans ce chaplLre, nous allons apprendre commenL desslner dans un JPanel vlde. Le JPanel vlde
serL de base a Lous les desslns en deux dlmenslons.
12.1. Les coordonnes
Lorsque l'on desslne dans un JPanel, le coln en hauL a gauche esL celul de coordonnees (0,0). L'axe
des x parL de ce polnL eL va vers la gauche. L'axe des y parL de ce polnL eL va vers le bas. Cela donne :
L'unlLe de l'axe des x eL de l'axe des y esL le plxel, en abrege px, qul esL l'unlLe de base eL slgnlfle
plctote elemeot. Cela correspondanL a un polnL sur l'ecran. ue nos [ours, la deflnlLlon normale
d'un ecran esL SCA, solL 1280 px sur 1024 px, ou uCA, solL 1600 px sur 1200 px.
138
uans un JPanel, les coordonnees negaLlves sonL en dehors du JPanel. un polnL de coordonnees
(x,y) apparaiL dans le !anel sl 0 x l eL 0 y L ou l esL la largeur du JPanel eL L esL la longueur
de noLre JPanel.
12.2. MVC
MVC (Mod|e - Vue- Contr|eur) esL un paLron de concepLlon (Jeslqo potteto) uLlllse
pour programmer les lnLerfaces uLlllsaLeurs.
MvC assume l'encapsulaLlon des donnees dans un mod|e. Le modele conLlenL LouL ce qul dolL Lre
afflche a l'ecran. L'lnLerface uLlllsaLeur peuL alors proposer une ou plusleurs vues de ce modele.
L'exemple classlque esL celul d'une Lable numerlque qul peuL Lre presenLe sous forme de Lable (vue
n 1) ou d'un graphlque (vue n 2). nous menLlonnerons le contr|eur dans le chaplLre sulvanL.
noLons egalemenL que pulsque le modele dolL Lre desslne, ll fauL qu'll n'y alL pas Lrop de Lravall
enLre le modele eL le dessln. Comme nous le verrons, le modele esL souvenL desslne eL sl le Lravall
qul permeL de passer du modele au dessln esL Lrop lmporLanL, l'lnLerface donnera l'lmpresslon de ne
plus reaglr (d'Lre fteez).
12.3. Le dess|n dans |es Iane|
Les desslns dans les JPanel sonL geres par une meLhode que possedenL Lous les composanLs de
!ava. La meLhode
protected void paintComponent(Graphics g)
de la classe JComponent esL la meLhode qul desslne dans les JPanel. CeLLe meLhode esL appelee
dans des clrconsLances que nous allons decrlre. Llle prend en argumenL un Graphics qul esL fournl
par !ava eL qul permeL de desslner dans le JPanel.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Graphics. Lxamlnez la classe.
La meLhode paintComponent esL de[a deflnle pour Lous les composanLs graphlques. 8edeflnlr
ceLLe meLhode pour un JPanel permeL de Lransformer le JPanel en zone de dessln.
Cuand ceLLe meLhode esL-elle appelee ? Les choses se compllquenL un peu. ll exlsLe en plus de voLre
programme un second processus leger appele veot ulspotcb 1bteoJ ou Lv1. Ce processus esL
execuLe en mme Lemps que voLre programme mals ll parLage la mme memolre 8AM. Cela slgnlfle
qu'll a acces aux mmes ob[eLs que voLre programme. Lv1 esL responsable de gerer une queue, la
veots Ooeoe, qul conLlenL des evenemenLs . Cn ne va s'lnLeresser qu'aux evenemenLs de
rafraichlssemenLs qul provoquenL l'appel a la meLhode paintComponent. C'esL l'Lv1 qul
declenche l'appel a la meLhode paintComponent lorsqu'un evenemenL le [usLlfle.
Cul meL des evenemenLs de rafraichlssemenL dans la veots Ooeoe ? 1ouL d'abord le programmeur,
s'll veuL qu'un JPanel jPanel solL repelnL, ll appelle la meLhode repaint() avec l'lnsLrucLlon :
jPanel.repaint() ;
139
CeLLe meLhode provoque la creaLlon d'un evenemenL de rafraichlssemenL de ce JPanel dans la
veots Ooeoe. Lorsque ceL evenemenL sera LralLe par l'Lv1, ll provoquera l'appel a la meLhode
paintComponent du JPanel. La deuxleme manlere de meLLre un evenemenL dans la veots
Ooeoe esL provoquee par le sysLeme lul-mme. Lorsque l'on meL avec la sourls une fenLre, quelle
qu'elle solL, devanL le JPanel, cela provoque la creaLlon d'un evenemenL de rafraichlssemenL pour
le JPanel dans la veots Ooeoe. Lorsque ceL evenemenL sera LralLe par l'Lv1, ll provoquera l'appel
a la meLhode paintComponent du JPanel.
12.4. Le mod|e de notre app||cat|on
Le mod|e de notre app||cat|on, commencee au chaplLre 11, devra conLenlr LouL ce qul esL
necessalre pour deLermlner l'eLaL de l'lnLerface graphlque. Cela comprend :
la llsLe des segmenLs de[a edlLes (ou crees) ,
la couleur couranLe de dessln ,
l'evenLuel segmenL en cours d'edlLlon afln de le desslner en polnLllle ,
l'evenLuel segmenL selecLlonne sl l'uLlllsaLeur en a selecLlonne un ,
un booleen dlsanL sl le modele a eLe modlfle afln de proposer une sauvegarde.
Chacun de ces elemenLs aura une represenLaLlon a l'ecran. Alnsl, le booleen deLermlnera sl le menu
Save as . esL acLlve ou pas. nous y revlendrons.
12.4.1. La c|asse Segment
Comme Lou[ours quand nous Lravalllons avec !ava, ll fauL rechercher sl ce que l'on veuL programmer
n'a pas eLe programme allleurs. Ln cherchanL un peu, on flnlL par Lrouver la classe Float qul esL
deflnle dans la classe Line2D (c.f. 10.3 Classes lmbrlquees) du package java.awt.geom. C'esL
une looet closs, classe lmbrlquee, une classe declaree a l'lnLerleur d'une auLre classe. La class Float
esL declaree a l'lnLerleur de la classe Line2D. Cn la reference sous le nom Line2D.Float.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Line2D.Float. Lxamlnez la classe eL sa classe mere.
CeLLe classe, ou sa classe mere, conLlenne LouLes les meLhodes qul vonL blen avec les segmenLs. ue
plus, les ob[eLs de ceLLe classe peuvenL Lre facllemenL desslnes avec des opLlons varlees, en
polnLllles par exemple. nous verrons cela plus loln. Cn va donc deflnlr une classe Segment dans un
package model. nous ra[ouLons une couleur dans noLre classe Segment :
package model ;
import java.awt.* ;
import java.awt.geom.* ;
public final class Segment extends Line2D.Float
{
private Color color ;
public Segment(float x1, float y1,
float x2, float y2, Color color)
{
super(x1,y1,x2,y2) ;
this.color = color ;
160
}
}
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Color. Lxamlnez la classe.
12.4.2. Le mod|e
MalnLenanL que nous avons noLre classe Segment, nous pouvons programmer noLre classe de
modele DrawingAppModel. Llle conLlenL ce qul a eLe enumere :
package model ;
import java.awt.* ;
import java.util.* ;
public final class DrawingAppModel
{
private final ArrayList<Segment> editedSegments ;
private Color currentColor ;
private Segment currentSegment ;
private Segment selectedSegment ;
private Boolean modified ;
public DrawingAppModel()
{
editedSegments = new ArrayList<Segment>() ;
currentColor = Color.BLACK ;
currentSegment = null ;
selectedSegment = null ;
modified = false ;
}
// Les getters et les setters
}
nous n'avons pas mls les qettets eL les settets afln de ne pas alourdlr ce chaplLre.
12.4.3. C mettre |e mod|e ?
Le plus slmple eL le plus evldenL esL de meLLre le modele dans la fenLre prlnclpale. Ln effeL, la
fenLre prlnclpale esL accesslble a Lous les composanLs qul devronL reaglr en foncLlon des acLlons de
l'uLlllsaLeur. Llle sera aussl accesslble a LouLes les meLhodes paintComponent de ces composanLs.
nous allons donc ra[ouLer dans la classe DrawingApp le code sulvanL :
private DrawingAppModel drawingAppModel = new DrawingAppModel() ;
public final DrawingAppModel getModel()
{
return drawingAppModel ;
}
public final void setModel(DrawingAppModel drawingAppModel)
161
{
this. drawingAppModel = drawingAppModel ;
}
12.S. Un exemp|e de dess|n dans un Iane|
nous allons monLrer un exemple slmple de dessln dans le Co|or Ind|cator qul esL un JPanel desLlne
a slmplemenL monLrer la couleur cholsle pour desslner les segmenLs. CeLLe couleur esL l'aLLrlbuL
currentColor du modele.
Les JPanel onL une couleur de fond (bockqtoooJ colot) que l'on peuL modlfler avec la meLhode :
public void setBackground(Color color) ;
La meLhode paintComponent de la classe JPanel se conLenLe de redesslner le fond avec la
couleur de fond. our desslner dans le JPanel, ll esL posslble de redeflnlr ceLLe meLhode. nous
allons essayer d'obLenlr le dessln sulvanL :
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Graphics. Lxamlnez la classe pour y Lrouver ce qu'll fauL
pour desslner la vue cl-dessus.
nous allons redeflnlr ceLLe meLhode dans la classe ColorIndicator dans lequel g esL l'ob[eL de
classe Graphics qul permeL de desslner sur le Co|or Ind|cator.
1ouL d'abord, nous allons desslner le fond d'ecran dans la couleur de fond par un appel a la
super meLhode de paintComponent :
super.paintComponent(g) :
uls nous allons obLenlr les dlmenslons du JPanel avec :
int w = getWidth() ;
int h = getHeight() ;
nous pouvons desslner le recLangle du mllleu avec la couleur de fond :
g.setColor(drawingApp.getModel().getCurrentColor()) ;
g.fillRect(4,4,w-8,h-8) ;
LL enfln, nous desslnons le cadre nolr auLour du recLangle du mllleu :
g.setColor(Color.BLACK) ;
g.drawRect(4,4,w-8,h-8) ;
162
nous allons donc ra[ouLer la meLhode sulvanLe dans la classe ColorIndicator :
@Override
protected final void paintComponent(Graphics g)
{
super.paintComponents(g) ; // paints the background
int w = getWidth() ; // widget dimensions
int h = getHeight() ;
g.setColor(drawingApp.getModel().getCurrentColor()) ;
g.fillRect(4,4,w-8,h-8) ;
g.setColor(Color.BLACK) ;
g.drawRect(4,4,w-8,h-8) ;
}
CeLLe meLhode sera appelee chaque fols qu'un evenemenL de rafraichlssemenL concernanL le Co|or
Ind|cator sera dans la veots Ooeoe, c.f. 12.3. un Lel evenemenL pourra Lre mls dans la veots
Ooeoe sl l'on appelle colorIndicator.repaint().
12.6. Graph|cs2D
La meLhode :
protected void paintComponent(Graphics g)
de la classe JComponent prend en argumenL un ob[eL de la classe Graphics. un ob[eL de la
classe Graphics peuL Lre converLl en un ob[eL de la classe Graphics2D qul esL blen plus
pulssanL. La classe Graphics2D herlLe de la classe Graphics afln de fournlr un conLrle plus
sophlsLlque sur les operaLlons de dessln en 2u. La converslon s'effecLue quand on le deslre dans la
meLhode paintComponent :
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g ;
}
Alnsl, on dlspose d'un ob[eL g2d de la classe Graphics2D egalemenL de desslner dans la
composanL. CeLLe classe possede des exLenslons permeLLanL des desslns evolues.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Graphics2D. Lxamlnez la classe.
Ln parLlculler, la classe Graphics2D esL capable de desslner les Line2D.Float qul onL servl de
base a nos segmenLs. Llle esL donc capable de desslner les ob[eLs de la classe Segment.
163
12.7. Un exemp|e de dess|n p|us soph|st|qu
nous allons redeflnlr la meLhode paintComponent(Graphics g) du Draw|ng ane|. Celle-cl
va d'abord redesslner la couleur de fond en appelanL la super meLhode de paintComponent
Lou[ours avec l'argumenL g :
super.paintComponent(g) ;
uls, ll va fallolr redesslner les dlfferenLs segmenLs qul sonL conserves dans le modele de Lype
DrawingAppModel. Mals fldele au prlnclpe de delegaLlon, pluLL que d'en exLralre les
lnformaLlons pour les desslner, nous allons demander au modele de desslner ses segmenLs. Cela
donne la meLhode sulvanLe a ra[ouLer dans la classe DrawingPanel :
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g) ;
drawingApp.getModel().paintSegment(g) ;
}
C'esL donc au modele DrawingAppModel de desslner les segmenLs. nous allons donc deflnlr une
meLhode de la classe Segment qul permeL de desslner les dlfferenLs segmenLs avec dlfferenLs
rendus selon leur eLaL :
s'll s'aglL du segmenL en cours d'edlLlon, on le desslne en polnLllle ,
s'll s'aglL du segmenL selecLlonne, on le desslne en plus gras ,
slnon, on le desslne normalemenL.
nous n'allons pas expllquer les rendus de la classe Graphics2D mals elles sonL basees sur des
ob[eLs de Lype BasicStroke que nous deflnlssons sous forme de varlable de classe dans la classe
Segment :
private final static float[] dash = { 4.0f } ;
private final static BasicStroke usualStroke ;
private final static BasicStroke largerStroke ;
private final static BasicStroke dashStroke ;
static {
usualStroke = new BasicStroke() ;
largerStroke = new BasicStroke(3.0f,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_MITER) ;
dashStroke = new BasicStroke(1.0f,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_MITER,
10,0f,
dash,
0.0f) ;
}
Ces varlables de classe de la classe Segment eLanL deflnles, nous allons deflnlr une meLhode paint
qul va prendre en argumenL un Graphics g, un booleen selected qul dlL sl le segmenL esL
selecLlonne eL un auLre current qul dlL sl le segmenL esL acLuellemenL en cours de dessln.
164
8appelons que la couleur de dessln du segmenL esL conLenue dans l'aLLrlbuL color de la classe
Segment. 8appelons egalemenL qu'un ob[eL de la classe Graphics2D esL capable de desslner un
ob[eL de la classe Segment. La meLhode se deflnlL alnsl dans la classe Segment :
public final void paintDashed(Graphics g)
{
Graphics2D g2d = (Graphics2D)g ;
g2d.setColor(color) ;
g2d.setStroke(dashStroke) ; // set to dashed rendering
g2d.draw(this) ; // draw the segment
g2d.setStroke(usualStroke) ; // restore to normal settings
}
public final void paintLarger(Graphics g)
{
Graphics2D g2d = (Graphics2D)g ;
g2d.setColor(color) ;
g2d.setStroke(largerStroke) ; // set to larger rendering
g2d.draw(this) ; // draw the segment
g2d.setStroke(usualStroke) ; // restore to normal rendering
}
public final void paintNormal()
{
Graphics2D g2d = (Graphics2D)g ;
g2d.setColor(color) ;
g2d.draw(this) ;
}
ll esL lmporLanL, apres avolr change le rendu, de le resLaurer. Slnon les auLres desslns uLlllseronL le
rendu modlfle.
A presenL, nous pouvons deflnlr la meLhode paintSegments de la classe DrawingAppModel :
public final void paintSegments(Graphics g)
{
for (Segment s : editedSegments)
s.paintNormal(g) ;
if (selectedSegment != null)
selectedSegment.paintLarger(g) ;
if (currentSegment != null)
currentSegment.paintDashed(g) ;
}
La meLhode paint de la classe DrawingPanel sera appelee chaque fols qu'un evenemenL de
rafraichlssemenL du Draw|ng ane| se Lrouvera dans la veots Ooeoe. Celle-cl demandera a l'ob[eL
modele d'execuLer la meLhode paintSegment cl-dessus.
163
12.8. Conc|us|ons
uans ceLLe secLlon, le plus lmporLanL a comprendre esL la secLlon 12.3 qul expllque quand la
meLhode paintComponent esL appelee. L'auLre aspecL esL la poslLlon domlnanLe du modele,
c'esL-a-dlre de l'ensemble de ce qul esL necessalre pour meLLre a [our l'lnLerface. nous y revlendrons
dans le chaplLre sulvanL.
167
13. MVC : mod|e, vue, contr|eur
(hors programme)
uans ceLLe secLlon, nous allons ldenLlfler commenL le modele du MvC (Modele-vue-ConLrleur), Lel
que decrlL en 12.2, s'lnsere dans l'lnLerface.
13.1. Les patrons de concept|on
Cn appelle patron de concept|on (Jeslqo potteto) une meLhode qul a falL ses preuves
eL peuL Lre reuLlllse dans des clrconsLances parLlculleres.
Le paLron de concepLlon esL une manlere d'organlser les classes de !ava. ll decrlL une organlsaLlon de
classes souvenL uLlllsee pour resoudre un probleme donne. Les paLrons de concepLlons servenL a
documenLer les bonnes praLlques, lls apporLenL un vocabulalre commun a un probleme. Le
programmeur uLlllsera le paLron de concepLlon comme gulde lors de l'elaboraLlon de son code
source eL, evenLuellemenL, l'adapLera a son probleme speclflque.
Les paLrons de concepLlon ne sonL pas speclflques a !ava, nl mme a l'lnformaLlque. Cn Lrouve des
paLrons de concepLlon dans Lous les domalnes.
(nors programme) Sl l'on s'lnLeresse aux paLrons de concepLlon, on pourra consulLer le llvre en
llgne Wlkl8ooks :
http://fr.wikibooks.org/wiki/Patrons_de_conception
13.2. ketour sur MVC
MVC (Mod|e - Vue- Contr|eur) esL un paLron de concepLlon (Jeslqo potteto) uLlllse
pour programmer les lnLerfaces uLlllsaLeurs. La vue esL une represenLaLlon graphlque
du mod|e.
nous avons vu le mod|e de noLre appllcaLlon, c'esL un ob[eL de la classe DrawingAppModel Lel
que decrlL en 12.2 eL 12.4.
168
1ouLe modlflcaLlon du mod|e dolL Lre repercuLee dans la vue graphlque.
13.3. Cbserver-Cbservab|e
Afln d'auLomaLlser le rafraichlssemenL de la vue quand le modele esL modlfle, !ava propose le paLron
de concepLlon (Jeslqo potteto) Cbserver-Cbservab|e :
La vue (DrawingApp) s'enreglsLre une seule fols aupres du mod|e (DrawingAppModel). Le
modele esL appele un Obsetvoble Landls que la vue esL appelee un Obsetvet. une fols enreglsLre
aupres du modele, chaque modlflcaLlon du modele devra noLlfler la vue grce a des foncLlons
speclales. une fols noLlflee, la vue se redesslne. Ln Lheorle, LouL esL auLomaLlque.
13.3.1. L'|nterface Cbserver
L'Obsetvet (la vue) dolL lmplemenLer |'|nterface Observer.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Observer. Lxamlnez l'lnLerface.
La vue dolL donc lmplemenLer l'unlque meLhode :
public void update(Observable observable, Object parameter) ;
CeLLe meLhode sera appelee par l'Obsetvoble (le mod|e) chaque fols que celul-cl sera modlfle. Sa
foncLlon esL, normalemenL, de rafraichlr la vue. Le parameLre parameter pourra Lre n'lmporLe
quel ob[eL qul sera Lransmls depuls l'Obsetvoble vers l'Obsetvet. Celul-cl esL opLlonnel.
13.3.2. La c|asse Cbservab|e
L'Obsetvoble (le mod|e) dolL Lre une sous-c|asse de la classe Observable.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Observable. Lxamlnez la classe.
un Obsetvet s'enreglsLre aupres de l'Obsetvoble en uLlllsanL la meLhode :
public void addObserver(Observer observer) ;
169
Lorsque l'Obsetvoble esL modlfle, ll dolL appeler sa meLhode :
protected void setChanged() ;
uls, lorsque l'Obsetvoble veuL noLlfler les Obsetvets, ll appelle l'une des deux meLhodes :
public void notifyObservers() ;
ou blen :
public void notifyObservers(Object parameter) ;
S'll uLlllse la deuxleme meLhode, c'esL qu'll veuL LransmeLLre un parameLre a la meLhode
public void update(Observable observable, Object parameter) ;
de l'Obsetvet.
13.4. L'Cbservab|e
Le modele de noLre appllcaLlon, la classe DrawingAppModel, dolL herlLer de la classe
Observable du package java.util :
package model ;
import java.util.* ;
import java.awt.* ;
public final class DrawingAppModel extends Observable
{
}
uans LouLes les meLhodes qul modlflenL le modele DrawingAppModel, sl ceLLe modlflcaLlon dolL
modlfler l'apparence de la fenLre graphlque, on a[ouLe un appel a setChanged() puls a la fln un
appel a notifyObservers().
Alnsl, par exemple, supposons une meLhode qul supprlme un des segmenLs (dans la ArrayList
editedSegment dans DrawingAppModel). Cela aura un effeL sur la represenLaLlon graphlque,
donc dans la classe DrawingAppModel :
public final void removeEditedSegment(Segment editedSegment)
{
editedSegments.remove(editedSegment) ;
modified = true ;
setChanged() ;
notifyObservers() ;
}
170
13.S. L'Cbserver
La vue DrawingApp dolL lmplemenLer l'lnLerface Observer du package java.util :
package ui ;
import javax.swing.* ;
import java.util.* ;
public final class DrawingApp extends JFrame
implements Observer
{
}
uonc, DrawingApp dolL lmplemenLer la meLhode :
public void update(Observable observable, Object parameter) ;
CeLLe meLhode dolL rafraichlr l'eLaL de l'lnLerface graphlque en foncLlon du modele. Lorsque
l'Obsetvoble DrawingAppModel esL modlfle, nous avons vu qu'll appelalL la meLhode :
update(observable, parameter)
de la fenLre prlnclpale. Les parameLres sonL observable qul esL le DrawingAppModel eL
parameter qul esL null car nous n'en avons pas eu besoln en secLlon precedenLe. uonc, dans
noLre cas, ces parameLres ne sonL pas uLlles car le modele, l'Obsetvoble, esL de[a connu de la fenLre.
Cue dolL falre la fenLre qul reolL ce message ?
Llle dolL redesslner la zone de dessln DrawingPanel.
Llle dolL redesslner le Lemoln ColorIndicator.
Llle dolL desacLlver le bouLon EraseSegment s'll n'y a pas de segmenL selecLlonne, ou
l'acLlver dans le cas conLralre.
our cela, la meLhode update de la classe DrawingApp va appeler une meLhode
notifyForUpdate() (sans parameLre) de la fenLre. Celle-cl appellera la mme meLhode sur
chacun de ses sous-composanLs eL alnsl de sulLe [usqu'au composanLs qul dolvenL Lre rafraichls. Ce
message sera donc propage [usqu'aux composanLs qul dolvenL Lre mls a [our.
public void update(Observable observable, Object parameter)
{
notifyForUpdate() ;
}
ll ne resLe plus qu'a programmer la cascade des message notifyForUpdate().
uans la classe DrawingApp :
public void notifyForUpdate()
{
windowPanel.notifyForUpdate() ;
}
171
uans la classe WindowPanel :
public void notifyForUpdate()
{
drawingPanel.notifyForUpdate() ;
buttonsPanel.notifyForUpdate() ;
}
uans la classe ButtonsPanel, ll n'y a que le colorIndicator eL le eraseSegment a
modlfler :
public void notifyForUpdate()
{
colorIndicator.notifyForUpdate() ;
eraseSegment.notifyForUpdate() ;
}
uans la classe ColorIndicator, on se conLenLe de falre un repaint() :
public void notifyForUpdate()
{
repaint() ;
}
La meLhode repaint() d'un composanL cree un evenemenL qul sera mls dans la veots Ooeoe eL
sera LralLe par la veot ulspotcb 1bteoJ (Lv1) comme expllque precedemmenL. Cuand ceLLe
evenemenL sera LralLe, la meLhode paintComponent(Graphics g) du composanL sera appele
eL le composanL sera redesslne en comme expllque en 12.3.
uans la classe EraseSegment, notifyForUpdate() se conLenLera d'acLlver ou de desacLlver le
bouLon en foncLlon du conLenu du selectedSegment du DrawingAppModel :
public void notifyForUpdate()
{
Segment selected = drawingApp.getModel().getSelectedSegment() ;
setEnabled(selected != null) ;
}
ll ne resLe plus que la classe DrawingPanel ou l'on va se conLenLer de falre un repaint() :
public void notifyForUpdate()
{
repaint() ;
}
La meLhode repaint() d'un composanL cree un evenemenL qul sera mls dans la veots Ooeoe eL
sera LralLe par la veot ulspotcb 1bteoJ (Lv1) comme expllque precedemmenL. Cuand ceLLe
evenemenL sera LralLe, la meLhode paintComponent(Graphics g) du composanL sera appele
eL le composanL sera redesslne en comme expllque en 12.7.
13.6. Conc|us|ons
nous avons flnl de programmer l'Obsetvet eL l'Obsetvoble.
L'Obsetvet (la vue fenLre DrawingApp) s'enreglsLre aupres de l'Obsetvoble (le modele
DrawingAppModel) a l'alde de la meLhode addObserver.
172
Les settets de l'Obsetvoble (le modele DrawingAppModel) onL eLe modlfles pour qu'lls noLlflenL
l'Obsetvet afln que la vue se rafraichlsse comme lndlque.
L'Obsetvet (la vue fenLre DrawingApp) propage hlerarchlquemenL le message de rafraichlssemenL
a Lous les composanLs (wlJqet) qul dolvenL Lre rafraichls.
Le mcan|sme est automat|s.
noLons encore une fols que noLre code esL verbeux, c'esL un cholx. Alnsl falL, les debuggages eL les
modlflcaLlons de code sonL blen plus faclles.
173
14. rogrammer son InM
(hors programme)
Le foncLlonnemenL d'une lnLerface graphlque SWlnC esL a base d'evenemenLs. Cn dlL
que SWlnC esL eveot-Jtlveo.
14.1. Les vnements
Chaque acLlon de l'uLlllsaLeur provoque la creaLlon d'un ob[eL evenemenL. ll exlsLe dlfferenLes classes
d'evenemenLs correspondanL aux dlfferenLs Lypes d'acLlons de l'uLlllsaLeur. L'appllcaLlon peuL elle-
mme generer des evenemenLs. 1ous les evenemenLs sonL sLockes dans une queue d'evenemenLs
que l'on appelle la veots Ooeoe. Cn rappelle qu'une queue esL une sLrucLure de donnees slmllalre a
une flle d'aLLenLe, c'esL-a-dlre une sLrucLure de Lype lllC (lltst lo - lltst oot).
Lxemp|e. nous connalssons de[a un Lype d'evenemenLs, c'esL celul des rafraichlssemenLs de
composanLs qul peuvenL Lre genere lorsque l'on masque ou que l'on falL reapparalLre le composanL.
lls peuvenL Lre aussl generer par l'appel a la meLhode repaint() du composanL.
14.2. Les tro|s processus |gers
Lorsque voLre programme s'execuLe, ll esL compose d'au molns deux processus legers.
Les processus legers (tbteoJs) sonL des programmes en cours d'execuLlon. un programme en cours
d'execuLlon esL aussl appele un flot Jexcotloo. Cn parle de processus legers lorsque ces processus
parLagenL les mmes donnees en memolre. Les deux processus sonL execuLes en parallele, c'esL-a-
dlre qu'lls se parLagenL la dlsponlblllLe du ou des processeurs de l'ordlnaLeur. CerLalns processus
peuvenL avolr une prlorlLe d'acces aux processeurs plus eleves que d'auLres.
174
Les deux processus donL nous avons parle sonL :
Le processus prlnclpal qul esL celul de voLre programme. ll commence a la meLhode maln de
voLre programme.
Le processus CC (Cotboqe collectot) qul s'occupe de la gesLlon de la memolre pour le compLe
de l'appllcaLlon.
Le programmeur peuL creer d'auLre processus mals nous n'en parlerons pas dans ce chaplLre.
Lorsque le programmeur cree une lnLerface graphlque avec SWlnC, un Lrolsleme
processus esL cree.
Ce processus, appele veot ulspotcb 1bteoJ ou Lv1, esL charge de recuperer les evenemenLs dans la
queue d'evenemenLs (veots Ooeoe) eL de les LralLer. Le LralLemenL d'un evenemenL conslsLe a
reLrouver l'ob[eL llsteoet, de Lype Listener, qul a eLe assocle a l'evenemenL eL a l'ob[eL qul a subl
l'evenemenL, puls a execuLer la meLhode approprlee de l'ob[eL Listener. C'esL blen enLendu le
programmeur qul speclfle ces ob[eLs llsteoets. Car c'esL alnsl qu'll programme les reponses de
l'lnLerface aux acLlons de l'uLlllsaLeur. Le programmeur n'esL pas obllge d'assocler un ob[eL llsteoet a
Lous les Lypes d'evenemenLs pour Lous les ob[eLs de l'lnLerface graphlque. ll n'assocle un ob[eL
llsteoet a un evenemenL que sl l'evenemenL l'lnLeresse. La pluparL des evenemenLs sonL
normalemenL lgnores.
8len que deflnl par le programmeur dans son programme, les llsteoets sonL execuLes
par la veot ulspotcb 1bteoJ (Lv1).
14.3. Mod|f|cat|on de |'|nterface
lmaglnons deux processus legers qul LenLenL de modlfler en mme Lemps l'lnLerface graphlque. L'un
pourralL voulolr desacLlver un bouLon Landls que l'auLre pourralL voulolr l'acLlver. Comme ces deux
processus s'execuLenL en parallele, le resulLaL pourralL Lre blzarre.
C'esL pourquol un seul processus leger a le drolL de modlfler l'lnLerface, c'esL le processus veot
ulspotcb 1bteoJ (Lv1) qul execuLe les meLhodes des ob[eLs llsteoets.
noLons que seul le processus veot ulspotcb 1bteoJ (Lv1) de SWlnC, eL donc les ob[eLs
llsteoets donL les meLhodes sonL execuLees par l'Lv1, a le drolL de modlfler l'lnLerface
graphlque.
Ln parLlculler, le processus leger correspondanL au programme prlnclpal (processus main) n'a plus le
drolL de modlfler l'lnLerface une fols qu'elle esL cree.
14.4. ketour sur |e mod|e MVC
173
nous avons de[a vu ma relaLlon enLre la vue eL le mod|e dans la paLron de concepLlon MvC a
Lravers l'auLre paLron de concepLlon Obsetvet-Obsetvoble dans le chaplLre 13. une Lrolsleme enLlLe
du paLron de concepLlon MvC esL appelee le contr|eur. Le contr|eur esL responsable des acLlons
qul seronL effecLuees. ll esL en parLlculler responsable des lnLeracLlons avec l'uLlllsaLeur de l'lnLerface
graphlque. Avec SWlnC, le contr|eur sera lmplemenLe en uLlllsanL des ob[eLs llsteoets.
La vue acLlonne les ob[eLs llsteoets a Lravers le mecanlsme de la queue d'evenemenLs (veots Ooeoe)
eL l'Lv1 decrlLes precedemmenL :
Le contr|eur, un ob[eL llsteoet, peuL modlfler les donnees dans le mod|e. LL le mod|e modlfle
demande a la vue de se rafraichlr a Lravers le paLron Obsetvet-Obsetvoble :
176
Cn peuL egalemenL souhalLer que le contr|eur, un ob[eL llsteoet, pulsse a la fols modlfler le mod|e
eL noLlfler la vue elle-mme pour qu'elle se rafraichlsse. Comme cecl :
Mals on preferera uLlllser le paLron Obsetvet-Obsetvoble car ll esL auLomaLlse. ll permeL aussl d'avolr
plusleurs vues pour un seul modele, ce qul n'esL pas evldenL avec ce dernler schema.
14.S. Aff|ner |es re|at|ons (hors programme)
Approche, nous avons uLlllse une approche Lres globale : une vue eL un mod|e. 1ouLe modlflcaLlon
du modele enLraine une modlflcaLlon de la vue. LsL-ce opLlmal ? Cuand on change la couleur de
dessln des segmenLs, fauL ll redesslner le panneau DrawingPanel ? non, pas forcemenL. lauL-ll
redeclder sl le bouLon EraseSegment dolL Lre acLlf ? non, pas forcemenL. Cuand on falL une
operaLlon sur un dessln, fauL-ll redesslner le ColorIndicator ? non, pas forcemenL.
C'esL pourquol on peuL proceder a un decoupage plus fln du modele avec des relaLlons Obsetvet-
Obsetvoble plus flne.
177
14.6. L|stener pour un I8utton
Lorsque l'on cllque sur un bouLon, un evenemenL de Lype ActionEvent esL genere. CeL
evenemenL dolL Lre LralLe par un ob[eL llsteoet de Lype ActionListener. ActionListener
esL une lnLerface qul demande a ce que l'on lmplemenLe la meLhode :
public void actionPerformed(ActionEvent e) ;
uonc, pour programmer un bouLon, ll fauL lul assocler un ob[eL de Lype ActionListener grce a
la meLhode addActionListener. Lorsque l'on cllquera sur le bouLon, un ActionEvent sera
mls dans la veots Ooeoe eL quand ll sera LralLe, la meLhode actionPerformed du llsteoet sera
execuLee par la veot ulspotcb 1bteoJ (Lv1).
uans la praLlque, le plus slmple esL que |e bouton so|t son propre ||stener.
14.6.1. Le bouton Lrase Segment
nous avons de[a programme le Lrase Segment en secLlon 11.17. Mals nous ne l'avons pas
programme. our le programmer, ll fauL lul ad[olndre un ob[eL llsteoet de Lype ActionListener.
Comme dlL dans la secLlon precedenLe, le plus slmple esL que le bouLon de Lype EraseSegment
solL son propre llsteoet. our cela, nous allons lul falre lmplemenLer ActionListener du
package java.awt.event.
package ui ;
import javax.swing.* ;
import java.awt.event.* ;
public class EraseSegment extends JButton
implements ActionListener
{
private final DrawingApp drawingApp ;
public EraseSegment(DrawingApp drawingApp)
{
super("Erase segment") ;
this.drawingApp = drawingApp ;
addActionListener(this) ;
}
public final void actionPerformed(ActionEvent evt)
{
drawingAppp.getModel().removeSelectedSegment() ;
}
}
L'acLlon du bouLon esL d'effacer le segmenL selecLlonne. lldele au prlnclpe de delegaLlon, nous
demandons au modele drawingApp.getModel() d'effecLuer ceLLe operaLlon. uans la classe du
modele DrawingAppModel, nous programmons la meLhode removeSelectedSegment :
178
public final void removeSelectedSegment()
{
Segment selectedSegment = this.selectedSegment ;
this.selectedSegment = null ;
removeEditedSegment(selectedSegment) ;
}
Cn sLocke l'aLLrlbuL selectedSegment couranL dans une varlable selectedSegment eL on
meL ceL aLLrlbuL a null. uls, on uLlllse la meLhode removeEditedSegment vue en 13.4. C'esL
ceLLe meLhode qul provoquera le rafraichlssemenL de l'lnLerface.
14.6.2. Le bouton Co|or Chooser
Le bouLon Co|or Chooser dolL permeLLre de cholslr une couleur qul devlendra celle du prochaln
segmenL desslne eL qul sera celle afflchee dans le Co|or Ind|cator. SWlnC propose une classe
JColorChooser qul permeL de creer une fenLre popup eL moda|e permeLLanL de cholslr une
couleur. Moda|e slgnlfle que les auLres fenLres de l'appllcaLlon seronL lnaccesslbles a l'uLlllsaLeur
LanL que ceLLe fenLre ne sera pas fermee. opup slgnlfle que la fenLre va [allllr eL sera une fenLre
fllle de la fenLre prlnclpale.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 JColorChooser. Lxamlnez la classe.
Comme souvenL avec ce genre de classe, la lecLure de la classe ne sufflL pas vralmenL a salslr LouLes
les nuances de la classe. uans ces cas-la, le mleux esL de chercher un LuLorlel en llgne :
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java JColorChooser tutorial.
179
une fols acquls les subLlllLes du JColorChooser, on peuL conLlnuer a programmer le
ColorChooser commence en 11.16 :
package ui ;
import javax.swing.* ;
import java.awt.event.* ;
public final class ColorChooser extends JButton
implements ActionListener
{
private final DrawingApp drawingApp ;
public ColorChooser(DrawingApp drawingApp)
{
super("Choose color") ;
this.drawingApp = drawingApp ;
addActionListener(this) ;
}
public void actionPerformed(ActionEvent evt)
{
DrawingAppModel model = drawingApp.getModel() ;
Color newColor
= JColorChooser.showDialog(drawingApp,
"Change segment color",
model.getCurrentColor()) ;
if (newColor != null)
model.setCurrentColor(newColor) ;
}
}
Sl le conLenu de la varlable newColor n'esL pas null, cela veuL dlre que vous n'avez pas appuye
sur la Louche d'annulaLlon (Cance| ou auLre chose) de la fenLre du JColorChooser. Sl elle n'esL
pas null, on appelle la meLhode setCurrentColor du modele qul provoquera le
rafraichlssemenL du modele.
14.7. L|stener pour un menu |tem
Les lLems de menu comme QuitMenuItem (11.6) sonL programmes comme les bouLons en
uLlllsanL des ActionListener. Cuand l'uLlllsaLeur selecLlonne le QuitMenuItem, le llsteoet dolL
verlfler sl le modele a eLe modlfle. Sl c'esL le cas, le llsteoet dolL proposer de sauver l'edlLlon couranLe
avec une fenLre popup eL moda|e du Lype es-No-coocel. Ce Lype de fenLre esL proposee par la
classe JOptionPane.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 JOptionPane eL aussl : JOptionPane tutorial.
lcl aussl, l'lLem de menu dolL Lre son propre de llsteoet :
180
package ui ;
import javax.swing.* ;
import java.awt.event.* ;
public final class QuitMenuItem extends JMenuItem
implements ActionListener
{
private final DrawingApp drawingApp ;
public QuitMenuItem(DrawingApp drawingApp)
{
super("Quit") ;
this.drawingApp = drawingApp ;
addActionListener(this) ;
}
public void actionPerformed(ActionEvent evt)
{
DrawingAppModel model = drawingApp.getModel() ;
if (model.isModified()) {
int response
= JOptionPane.showInternalOptionDialog
(this,
"Not saved. Save it ?",
"Quit Application",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
null,
null) ;
switch (response) {
case JOptionPane.CANCEL_OPTION:
return ;
case JOPtionPane.OK_OPTION:
model.saveToFile() ;
break ;
case JOptionPane.NO_OPTION:
break ;
}
System.exit(0) ;
}
}
Cn a suppose que le model a une meLhode saveToFile() qul sauvegarde l'edlLlon couranLe dans
un flchler.
14.8. L|stener pour |a sour|s
1ous les composanLs peuvenL ecouLer la sourls de l'uLlllsaLeur. Cela slgnlfle que Lous les composanLs
peuvenL, a Lravers des ob[eLs llsteoets, Lre prevenus de ce qul se passe avec la sourls. ll exlsLe Lrols
Lypes d'ob[eLs llsteoets correspondanL a dlfferenLs evenemenLs. Ces ob[eLs llsteoets sonL caracLerlses
181
par des lnLerfaces, les lnformaLlons uLlles sonL dans l'evenemenL qul esL donne en argumenL aux
meLhodes requlses par ces lnLerfaces :
MouseListener demande a ce que l'on meLLe en ouvre les meLhodes :
o public void mouseClicked(MouseEvent e) ;
dans le cas ou ll y a eu un cllc de sourls.
o public void mouseEntered(MouseEvent e) ;
dans le cas ou la sourls enLre dans le composanL.
o public void mouseExited(MouseEvent e) ;
dans le cas ou la sourls sorL du composanL.
o public void mousePressed(MouseEvent e) ;
dans le cas ou un bouLon de la sourls esL presse.
o public void mouseReleased(MouseEvent e) ;
dans le cas ou un bouLon de la sourls esL relche apres avolr eLe presse.
MouseMotionListener demande a ce que l'on meLLe en ouvre les meLhodes :
o public void mouseDragged(MouseEvent e) ;
dans le cas ou la sourls esL deplace avec le bouLon enfonce.
o public void mouseMoved(MouseEvent e) ;
dans le cas ou la sourls esL deplace.
MouseWheelListener demande a ce que l'on meLLe en ouvre les meLhodes :
o public void mouseWheelMoved(MouseWheelEvent e) ;
dans le cas ou la molleLLe de la sourls esL Lournee.
lmaglnons que vous voullez ecouLer les double-cllcs de sourls falLs avec le bouLon drolL
de la sourls. uans ce cas, le plus slmple esL d'uLlllser voLre navlgaLeur prefere eL voLre
moLeur de recherche eL de rechercher commenL falre.
uu falL qu'll faudralL lmplemenLer les nombreuses meLhodes des lnLerfaces, que celles-cl ne sonL pas
Lou[ours uLlles, ll peuL devenlr fasLldleux que le composanL lul-mme solL son propre ob[eL llsteoet de
sourls en declaranL qu'll lmplemenLe ces lnLerfaces. La classe MouseAdapter lmplemenLe les
lnLerfaces cl-dessus. uans ceLLe lmplemenLaLlon, les dlfferenLes meLhodes exlsLenL mals ne fonL rlen.
Llles sonL desLlnees a Lre redeflnles. CeLLe classe esL desLlnee a Lre herlLee pour deflnlr un ob[eL
llsteoet de sourls.
our deflnlr un ob[eL llsteoet de sourls, on deflnlL une classe qul herlLe de la classe
MouseAdapter puls on ne redeflnlL que les meLhodes qul nous lnLeressenL.
une fols l'ob[eL llsteoet eLabll, ll fauL l'a[ouLer aux ob[eLs llsteoets du composanL grce aux meLhodes
addMouseListener, addMouseMotionListener eL addMouseWheelListener.
182
14.8.1. Un exerc|ce
A LlLre d'exemple, nous allons creer un ob[eL llsteoet de sourls qul se conLenLe d'afflcher les
evenemenLs dans la Conso|e :
public class MouseDisplay extends MouseAdapter
{
@Override
public void mouseClicked(MouseEvent e)
{
System.out.println("Mouse clicked : " + e) ;
}
@Override
public void mouseDragged(MouseEvent e)
{
System.out.println("Mouse dragged : " + e) ;
}
@Override
public void mouseEntered(MouseEvent e)
{
System.out.println("Mouse entered : " + e) ;
}
@Override
public void mouseExited(MouseEvent e)
{
System.out.println("Mouse exited : " + e) ;
}
@Override
public void mouseMoved(MouseEvent e)
{
System.out.println("Mouse moved : " + e) ;
}
@Override
public void mousePressed(MouseEvent e)
{
System.out.println("Mouse pressed : " + e) ;
}
@Override
public void mouseReleased(MouseEvent e)
{
System.out.println("Mouse released : " + e) ;
}
@Override
public void mouseWheelMoved(MouseEvent e)
{
System.out.println("Mouse wheel moved : " + e) ;
}
}
183
CeLLe classe esL une classe d'ob[eL llsteoet de sourls car elle herlLe de MouseAdapter eL donc
lmplemenLe les Lrols lnLerfaces de[a vue. Sl un composanL deslre l'avolr comme ob[eL llsteoet de
sourls, ll sufflL qu'll meLLe les lnsLrucLlons sulvanLes dans le consLrucLeur :
MouseDisplay mouseDisplay = new MouseDisplay() ;
addMouseListener(mouseDisplay) ;
addMouseMotionListener(mouseDisplay) ;
addMouseWheelListener(mouseDisplay) ;
CeL ob[eL llsteoet afflche les evenemenLs. ll peuL donc Lre lnsLrucLlf de le meLLre comme ob[eL
llsteoet sur un composanL.
14.8.2. Dess|ner un segment
uans noLre DrawingPanel, nous allons desslner des segmenLs alnsl :
on cllque a l'orlglne du segmenL ,
on garde le bouLon de la sourls enfonce ,
on deplace le polnLeur de sourls [usqu'a l'exLremlLe du segmenL ,
on relche le bouLon de la sourls.
Sl la sourls sorL du DrawingPanel duranL ces operaLlons, l'edlLlon esL abandonnee.
Cn a donc besoln d'un ob[eL llsteoet de sourls qul s'lnLeresse aux evenemenLs : mousePressed,
mouseReleased, mouseExited eL mouseDragged. CeL ob[eL llsteoet de sourls devra avolr
acces au modele pour aglr. nous allons creer un DrawingPanelMouseListener :
package ui ;
import java.awt.event.* ;
public final DrawingPanelMouseListener extends MouseAdapter
{
private final DrawingApp drawingApp ;
public final DrawingPanelMouseListener(DrawingApp drawingApp)
{
this.drawingApp = drawingApp ;
}
}
eL nous allons redeflnlr les quaLre foncLlons clLees cl-dessus. uls, nous aLLacherons ceL ob[eL au
DrawingPanel comme lndlque dans le chaplLre precedenL en ra[ouLanL les lnsLrucLlons sulvanLes
a la fln du consLrucLeur de DrawingPanel :
DrawingPanelMouseListener mouseListener
= new DrawingPanelMouseListener() ;
addMouseListener(mouseListener) ;
addMouseMotionListener(mouseListener) ;
addMouseWheelListener(mouseListener) ;
A presenL voyons commenL nous redeflnlssons les quaLre foncLlons clLees plus hauL.
184
Lorsque l'on reolL le message mousePressed, ll fauL creer le segmenL couranL
(currentSegment) dans le modele avec les coordonnees dlsponlbles dans le MouseEvent. Cn
redeflnlL donc ceLLe foncLlon dans DrawingPanelMouseListener :
@Override
public final void mousePressed(MouseEvent e)
{
DrawingAppModel model = drawingApp.getModel() ;
model.initCurrentSegment(e.getX(),e.getY()) ;
}
La meLhode initCurrentSegment du modele dolL lnlLlallser l'aLLrlbuL currentSegment puls
provoquer un rafraichlssemenL de l'ecran comme lndlque dans les chaplLres precedenLs.
Lorsque l'on reolL le message mouseDragged, la sourls a eLe bougee avec le bouLon enfonce, ll
fauL donc modlfler le segmenL couranL dans le modele avec les nouvelles coordonnees dlsponlbles
dans le MouseEvent :
@Override
public final void mouseDragged(MouseEvent e)
{
DrawingAppModel model = drawingApp.getModel() ;
model.modifyCurrentSegment(e.getX(),e.getY()) ;
}
La meLhode modifyCurrentSegment du modele dolL prendre le segmenL couranL eL modlfler
son exLremlLe avec ses argumenLs. uls elle dolL provoquer un rafraichlssemenL de l'ecran comme
lndlque dans les chaplLres precedenLs.
Lorsque l'on reolL le message mouseReleased, ll fauL modlfler le segmenL couranL avec les
coordonnees dlsponlble dans le MouseEvent. uls ll fauL enreglsLrer le segmenL couranL en LanL
que segmenL edlLe. uls, enfln, ll fauL provoquer un rafraichlssemenL de l'ecran. uonc :
@Override
public final void mouseReleased(MouseEvent e)
{
DrawingAppModel model = drawingApp.getModel() ;
model.registerCurrentSegment(e.getX(),e.getY()) ;
}
1ouL cecl foncLlonne forL blen sauf qu'un slmple cllc de sourls provoque Lrols evenemenLs dans
l'ordre : mousePressed, mouseReleased eL mouseClicked. Cela slgnlfle que
registerCurrentSegment ne dolL enreglsLrer le segmenL couranL en LanL que segmenL edlLe
que sl le segmenL couranL esL de longueur non nulle.
Lnfln, sl l'on reolL le message mouseExited, ll fauL abandonner le segmenL couranL :
@Override
public final void mouseExited(MouseEvent e)
{
DrawingAppModel model = drawingApp.getModel() ;
model.cancelCurrentSegment() ;
}
La foncLlon cancelCurrentSegment du modele efface le segmenL couranL eL provoquera le
rafraichlssemenL de l'ecran.
183
Lncore une fols, LouL cecl foncLlonne Lres blen mals ll y a un probleme. Sl l'on sorL de la zone de
dessln avec la sourls, la valeur de currentSegment devlenL null. CependanL, sl l'on n'a pas
relche le bouLon, les emlsslons mouseDragged eL mouseReleased conLlnuenL d'arrlver. Mals
ces evenemenLs provoquenL les appels des meLhodes correspondanLes qul accedenL a l'ob[eL
currentSegment eL donc provoquenL des excepLlons de Lype NullPointerException. Ces
excepLlons n'apparalssenL pas car la veot ulspotcb 1bteoJ (Lv1) arrLe les excepLlons avec un bloc
try-catch. our corrlger cela, ll fauL donc dans modifyCurrentSegment eL dans
registerCurrentSegment LesLer sl currentSegment esL null ou pas.
14.8.3. rogrammons |a s|ect|on
Cn selecLlonne un segmenL en cllquanL dessus.
@Override
public final void mouseClicked(MouseEvent e)
{
DrawingAppModel model = drawingApp.getModel() ;
model.setSelection(e.getX(),e.getY()) ;
}
uls dans DrawingAppModel :
public final void setSelection(int x, int y)
{
// concerts coordinates in double
double xd = (double)x ;
double yx = (double)y ;
// find a segment at less that 1 pt of (xd,yd)
for (Segment s : editedSegments) {
if (s.ptLineDist(xd,yd) < 1.0) {
setSelectedSegment(s) ;
return ;
}
}
// no segment has been found
setSelectedSegment(null) ;
}
14.9. Les autres ||steners
ll exlsLe blen d'auLres Lypes d'ob[eLs llsteoets. lls lmplemenLenL Lous l'lnLerface EventListener.
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 EventListener. Lxamlnez les classes qul lmplemenLenL
ceLLe lnLerface.
CerLalns de ces ob[eLs llsLeners sonL Lres lmporLanLs :
KeyListener pour ecouLer les evenemenLs clavlers.
WindowListener pour ecouLer les evenemenLs relaLlfs aux fenLres.
FocusListener pour ecouLer les evenemenLs relaLlfs aux focus des fenLres.
186
CerLalns permeLLenL de reallser du utoq ooJ utop.
14.10. Conc|us|ons
Les composanLs qul onL besoln d'un ActionListener peuvenL Lre hybrldes, c'esL-a-dlre Lre a la
fols wlJqet (composanL) eL Lre leur propre ob[eL llsteoet. C'esL plus slmple de proceder alnsl eL le
code relaLlf au composanL esL locallse dans une classe.
Les composanLs qul onL besoln d'un ob[eL llsteoet de sourls. ll cree leur ob[eL llsteoet de sourls en
programmanL une classe qul herlLe de MouseAdapter eL en redeflnlssanL cerLalnes des meLhodes.
Les ob[eLs llsteoets ne fonL rlen par eux-mmes. lls deleguenL les operaLlons au
mod|e. Cela permeL de locallser le code relaLlf a ces operaLlons.
14.11. In f|ne
1. ConsLrulre l'lnLerface (la Vue) comme une hlerarchle de !anel conLenanL des composanLs
agences par des loyoots. CerLalns !anel peuvenL Lre uLlllses comme zone de dessln. Chaque
composanL garde des references sur ses sous composanLs. Les composanLs reaglssanLs gardenL
une reference sur la fenLre prlnclpale. ueflnlr une classe par composanL. 1esLer.
2. ueflnlr le Mod|e conLenanL les donnees de l'appllcaLlon eL cerLalns elemenLs deflnlssanL des
proprleLes de la Vue. MeLLre le Mod|e en aLLrlbuL de la fenLre. Appllquer le paLron de
concepLlon Obsetvet-Obsetvoble enLre la Vue eL le Mod|e. 1esLer.
3. Modlfler les settets du Mod|e pour qu'lls provoquenL des noLlflcaLlons a la Vue. ALLenLlon de ne
pas provoquer des noLlflcaLlons lnuLlles. rogrammer les meLhodes de mlse a [our de la vue.
1esLer.
4. rogrammer de manlere lncremenLale les dlfferenLs llsteoets eL les assocler aux composanLs. ue
preference, les llsteoets dolvenL se conLenLer d'aglr sur le Mod|e. 1esLer au fur eL a mesure.
187
1S. L|ments de programmat|on C.C.
(hors programme)
nous avons de[a vu cerLalns prlnclpes lnconLournables :
Le pr|nc|pe d'encapsu|at|on.
Le pr|nc|pe de non-|ntrus|on.
Le pr|nc|pe de d|gat|on.
L'uLlllsaLlon des |nterfaces de programmat|on.
1S.1. Le pr|nc|pe d'encapsu|at|on
Le pr|nc|pe d'encapsu|at|on conslsLe prlnclpalemenL a quallfler Lous les aLLrlbuLs avec
le moL cle private eL a fournlr les foncLlons d'acces (qettets) eL les foncLlons de
modlflcaLlons (settets) necessalres au foncLlonnemenL de l'appllcaLlon.
Le prlnclpe d'encapsulaLlon permeL de preserver la coherence des sLrucLures de donnees en assuranL
que les aLLrlbuLs resLenL conformes a un lnvarlanL de classe.
Le prlnclpe d'encapsulaLlon permeL de preserver l'lnLegrlLe des sLrucLures de donnees en conLrlanL
la valldlLe des affecLaLlons.
Le prlnclpe d'encapsulaLlon permeL de garanLlr la coherence de l'appllcaLlon, par exemple la
coherence enLre la vue (represenLee par l'lnLerface graphlque) eL le Modele (represenLee par els
donnees).
Le prlnclpe d'encapsulaLlon permeL d'assurer la Lransparence des mlses en ouvre des classes
d'ob[eLs car le code des foncLlons d'acces esL cache.
1S.2. Le pr|nc|pe de non-|ntrus|on
Le pr|nc|pe de non-|ntrus|on speclfle que l'on evlLe de Lravalller sur un ob[eL depuls
l'exLerleur de l'ob[eL.
188
Sl l'on dolL reallser une operaLlon sur un ob[eL, c'esL l'ob[eL qul dolL fournlr une meLhode pour ceLLe
operaLlon.
Lxemp|e. Cn peuL lmaglner une classe Point (secLlon 2.12) qul fournlL les settets pour ses
coordonnees. Sl l'on veuL deplacer un polnL p :
p.setX(p.getX() + dx) ;
p.setY(p.getY() + dy) ;
ll esL recommande que la classe Point fournlsse une meLhode :
public final void move(int dx, int dy)
eL de lalsser le polnL falre lul-mme son deplacemenL. Le programme n'en sera que plus llslble eL plus
efflcace.
1S.3. Le pr|nc|pe de d|gat|on
Le pr|nc|pe de d|gat|on speclfle que les ob[eLs dolvenL Lre paresseux : sl un ob[eL a
une Lche a accompllr, ll essale de deleguer ceLLe Lche a un auLre ob[eL.
Alnsl, le bouLon C|ear de nos lPM (secLlon 1.6.2) pourralL posseder des references sur les champs
d'enLree eL effacer lul-mme les conLenus des ces champs. Mals sl l'on declde d'a[ouLer un nouveau
champ d'enLree, ll faudra modlfler LouLes les meLhodes qul fonL reference aux champs d'enLree. LL ll
esL posslble d'en oubller. Au lleu de cela, le bouLon C|ear delegue l'operaLlon a la fenLre qul lul-
mme le deleguera au panneau qul conLlenL les champs d'enLree qul lul-mme effacera les champs
d'enLree grce a une meLhode clearFields(). Sl l'on deslre ra[ouLer un nouveau champs
d'enLree, on le ra[ouLera dans le panneau eL on modlflera sa meLhode clearFields().
L'avanLage, c'esL que sl l'on dolL modlfler l'lPM, les modlflcaLlons seronL locales. L'lnconvenlenL, c'esL
que cela demande plus de code. Mals plus slmple a ecrlre eL rellre.
1S.4. Les |nterfaces de programmat|on
L'uLlllsaLlon des |nterfaces de programmat|on lors de la phase de concepLlon esL un
excellenL prlnclpe.
L'lnLerface de programmaLlon esL un out|| de concept|on : on pense l'lnLerface avanL de penser la
classe.
L'lnLerface de programmaLlon esL un contrat qul engage les dlfferenLs developpeurs.
L'lnLerface de programmaLlon esL un out|| d'encapsu|at|on qul permeL de ne monLrer qu'une faceLLe
d'un ob[eL.
L'lnLerface de programmaLlon esL un out|| de catgor|sat|on qul permeL de decrlre une proprleLe
parLagee par dlfferenLes caLegorles d'ob[eL.
189
1S.S. L'env|ronnement d'un ob[et
Lorsque l'on conolL une soluLlon orlenLee ob[eL a un probleme, ll esL lmporLanL de
deLermlner les env|ronnements des ob[ets qul apparaiLronL dans le probleme.
L'envlronnemenL d'un ob[eL esL compose des auLres ob[eLs qu'll connaiL. un ob[eL connaiL un auLre
ob[eL s'll possede dans ses aLLrlbuLs une reference sur celul-cl. L'envlronnemenL dolL Lre mlnlmal en
foncLlon du prlnclpe de delegaLlon. Alnsl le bouLon C|ear de nos lPM n'a pas a connaiLre le conLenu
de la fenLre. Ces aLLrlbuLs dolvenL Lre declares private pour empcher qu'un ob[eL exLerleur ne
s'en serve (prlnclpe d'encapsulaLlon). L'envlronnemenL d'un ob[eL dolL Lre eLabll a la creaLlon de
l'ob[eL. Cela peuL poser de peLlLs problemes d'lmplemenLaLlon lorsque deux ob[eLs dolvenL
muLuellemenL se connaiLre.
1S.6. InM et env|ronnements des ob[ets graph|ques
Lorsque l'on conolL les envlronnemenLs des ob[eLs graphlques d'une lPM, ll y a deux
manleres de proceder.
La premlere manlere esL la manlere Lres slmpllflee que nous avons adopLee au chaplLre 11. 1ouL
passanL par la fenLre prlnclpale, l'envlronnemenL d'un ob[eL graphlque esL compose des ob[eLs qu'll
conLlenL. Llle fournlL un code plus lourd mals Lres slmple a ecrlre, presque ennuyeux. Llle faclllLe la
relecLure du code eL les evoluLlons fuLures du loglclels.
une manlere plus opLlmlsee conslsLe a Lresser des llens plus serres enLre les ob[eLs, par exemple en
falsanL en sorLe que le bouLon C|ear connalsse le panneau qul conLlenL les champs d'enLree. Le code
sera probablemenL plus compacL mals aura une complexlLe accrue qul rendra malalsee les evoluLlons
fuLures du loglclel eL la recherche de bugs.
1S.7. Catgor|ser |es ob[ets
Lorsque l'on aLLaque un probleme, on commence par ldenLlfler les ob[eLs eL les
caLegorles d'ob[eLs presenLes dans le probleme. Chacune des caLegorles donnera lle a
un package.
Les caLegorles d'ob[eLs peuvenL conLenlr des ob[eLs reels comme des roboLs eL des ob[eLs plus
vlrLuels comme le llen enLre le roboL eL le posLe de commandes. un package esL un regroupemenL
loglque de classes eL d'lnLerfaces. Celles-cl sonL physlquemenL regroupees dans un reperLolre. Les
packages sonL represenLes sous la forme d'une arborescence car ll peuL y avolr des packages a
l'lnLerleur de packages.
Les packages compllquenL un peu la programmaLlon car ll y a necesslLe d'lmporLer le package pour
en uLlllser les classes eL les lnLerfaces eL ll y a necesslLe d'lndlquer ou Lrouver les classes eL les
lnLerfaces des packages. CependanL, lls permeLLenL de mleux sLrucLurer le code.
Lxemple de packages : un Lype de donnees, une boiLe a ouLlls (toolbox), une foncLlon speclflque (par
exemple les l/C), le code non porLable (rare en !ava), les elemenLs graphlques de l'lPM, un canal de
communlcaLlon enLre deux ob[eLs, eLc.
190
1S.8. L'hr|tage
L'herlLage a une foncLlon de modellsaLlon des elemenLs du probleme.
LLanL donnee une classe d'ob[eLs, on la part|t|onne en sous-classes speclallsees. Alnsl une classe
d'ob[eLs graphlques Shape, represenLanL les ob[eLs graphlques en general, sera parLlLlonne en des
sous-classes speclallsees : Circle, Square, eLc.
LLanL donnee une classe d'ob[eLs, on peuL egalemenL la raff|ner ou se spc|a|lser en creanL une sous-
classe. ar exemple, une classe generale Student peuL Lre speclallse en une classe 1SLudenL
decrlvanL les speclflclLes des eLudlanLs de 1elecom arls1ech.
La speclallsaLlon peuL se falre par enr|ch|ssement de la classe ou par redf|n|t|on des meLhodes de la
classe ou les deux a la fols.
1S.9. nr|tage vs. Compos|t|on
L'erreur la plus couranLe en modellsaLlon orlenLee ob[eL esL de confondre herlLage eL
composlLlon.
Alnsl la classe Vehicule (vehlcule) n'herlLe pas de la classe Engine (moLeur) mals la classe
Vehicule a un aLLrlbuL de Lype Lnglne car un vehlcule esL compose d'un moLeur, de quaLre roues,
eLc. un auLre exemple, volr plus bas, esL un Segment dolL avolr deux aLLrlbuLs de Lype Point eL
non Lre un Point eLendu avec un auLre Point.
Confondre herlLage eL composlLlon genere un code Lres complexe eL peuL parfols empcher d'aller
[usqu'au bouL.
Lxemp|e. L'erreur :
public class Segment extends Point
{
private Point extremity ;
}
La bonne soluLlon :
public class Segment
{
private Point origin ;
private Point extremity ;
}
191
1S.10. L'erreur !
ll esL preferable que le comporLemenL d'un ob[eL solL decrlL par sa classe que dedulL de
la valeur de ses aLLrlbuLs.
Sauf, blen evldemmenL, lorsque c'esL beaucoup plus slmple de falre auLremenL ! Alnsl, on evlLera les
LralLemenLs par cas, par exemple des lnsLrucLlons switch, dependanL des aLLrlbuLs afln de
deLermlner le comporLemenL de l'ob[eL. Cela permeL de rendre le code plus facllemenL modulalre eL
exLenslble comme le monLrera l'exemple des expresslons arlLhmeLlques dans ce chaplLre.
1S.1. Le sous-c|assement
Lorsque l'on modellse un Lype d'ob[eL, on esL souvenL amene a deflnlr des sous-classes
de ce Lype.
Le Lype d'ob[eL va Lre parLlLlonne en dlfferenLs sous-Lypes, chacun eLanL ldenLlfles par une proprleLe
parLlcullere. Alnsl, ldealemenL, les enLlers devralenL Lre parLlLlonnes en les enLlers poslLlfs, zero eL
les enLlers negaLlfs. Sl l'on devalL sous-classer les booleens, ll y a deux comporLemenL posslbles : celul
du booleen vral eL celul du booleen faux. Cn cree deux sous-classes : celle des booleens vral eL celle
des booleens faux. !usqu'ou fauL-ll sous-classer ? 1ouL esL affalre de mesure.
Au seln d'une caLegorle generale, on ldenLlflera les sous-caLegorles qul onL un comporLemenL
parLlculler :
192
Cela donnera un graphe d'herlLage come celul-cl :
ll exlsLe un cas parLlculler, c'esL quand le parLlLlonnemenL esL compleL. uans ce cas, ll n'y a pas
d'ob[eL sans comporLemenL parLlculler :
193
Cn a alors une classe de base absLralLe :
1S.2. Notre exemp|e : |es express|ons ar|thmt|ques
Supposons que l'on veullle ecrlre un programme de calculaLrlce elecLronlque. ll faudra consLrulre une
belle lPM. uls le cour de la calculaLrlce devra repeLer les operaLlons sulvanLes :
analyser ce que l'uLlllsaLeur a enLre ,
consLrulre un ob[eL de Lype expresslon correspondanL ,
evaluer ceL ob[eL ,
afflcher le resulLaL.
La classe Expression represenLanL les expresslons arlLhmeLlques esL l'ob[eL de noLre exemple.
1S.2.1. Les express|ons
une expresslon esL solL une consLanLe (nombre floLLanL), solL une addlLlon de deux expresslons, solL
une sousLracLlon de deux expresslons, solL une mulLlpllcaLlon de deux expresslons, solL une dlvlslon
de deux expresslons. nous allons commencer par penser le comporLemenL des expresslons eL deflnlr
les lnLerfaces des dlfferenLes classes.
La calculaLrlce elecLronlque demandera sa valeur a une expresslon. ll y aura donc une meLhode pour
evaluer l'expresslon. CeLLe meLhode sera suscepLlble de declencher une erreur de Lype
ArithmeticException en cas de dlvlslon par zero par exemple.
La calculaLrlce elecLronlque voudra sauver l'eLaL de son hlsLorlque dans un flchler. ll faudra y
sauvegarder les expresslons presenLes dans l'hlsLorlque. Cn demandera donc a l'expresslon de
s'ecrlre dans un ob[eL de Lype PrintWriter. CeLLe meLhode sera suscepLlble de declencher des
erreurs de Lype IOException.
C'esL la responsablllLe du programme englobanL d'arrLer ces excepLlons eL de les LralLer en afflchanL
un message d'erreur par exemple.
nous cholslssons un package nomme expressions afln de recuellllr nos classes eL lnLerfaces. La
classe des expresslons sera nommee Expression eL son lnLerface ExpressionInterface.
194
L'lnLerface des expresslons se nomme ExpressionInterface :
package expressions ;
public interface ExpressionInterface
{
// Returns the value of the expression.
public double eval()
throws ArithmeticException ;
// Outputs a text representation of the expression.
public void writeTo(PrintWriter printWriter)
throws IOException ;
}
1S.2.2. Notes sur |e processus de dve|oppement
noLons qu'en connalssanL ceLLe lnLerface, le programmeur peuL de[a ecrlre une Lres grande parLle du
programme de calculaLrlce. ll ne manque que les slgnaLures des consLrucLeurs de la classe des
expresslons pour consLrulre l'expresslon enLree par l'uLlllsaLeur.
Sl l'on deslre que la calculaLrlce elecLronlque pulsse Lre programme sans la programmaLlon des
expresslons, ll sufflL de deflnlr une classe ExpressionParser chargee d'analyser les chaines de
caracLeres enLrees par l'uLlllsaLeur pour en exLralre une expresslon :
package expressions ;
public final class ExpressionParser
{
// This function parses a string representating an expression.
// and returns the corresponding expression.
public static final ExpressionInterface parse(String source)
{
return null ;
}
}
Cn programme la calculaLrlce en uLlllsanL ceLLe foncLlon qul ne falL rlen. normalemenL, le
programme de la calculaLrlce devralL se compller mals ne pourra pas Lre execuLe pulsque les
expresslons n'y sonL pas deflnles.
L'lnsLrucLlon return null sera remplacee par de verlLables lnsLrucLlons quand les expresslons
seronL developpees. Ln aLLendanL, le resLe des programmeurs peuL Lravalller, mas par LesLer, car
nous avons encapsule les expresslons dans un package eL nous avons fournl aux auLres
programmeurs l'lnLerface necessalre a leur Lravall.
1S.2.3. Une mauva|se |mp|mentat|on des express|ons
volcl une lmplemenLaLlon de la classe Lxpresslon lnsplree de la programmaLlon classlque. ue falL,
une Lelle lmplemenLaLlon pourralL Lre redlgee dans n'lmporLe quel langage non orlenLe ob[eL :
193
package expressions ;
public final class Expression
implements ExpressionInterface
{
// This is the type of the expression :
// #c# for constant
// #+# for addition
// #-# for substraction
// #*# for product
// #/# for division
private final char expressionType ;
// Used when expression is a constant
private final double value ;
// Used for binary operation : left operand
private final ExpressionInterface leftOp ;
// Used for binary operation : right operand
private final ExpressionInterface rightOp ;
// Constructor for constant
public Expression(double value)
{
this.expressionType = #c# ;
this.value = value ;
this.leftOp = null ;
this.rightOp = null ;
}
// Constructor for binary expression
public Expression(char expressionType,
ExpressionInterface leftOp,
ExpressionINterface rightOp)
{
this.expressionType = expressionType ;
this.value = 0.0 ;
this.leftOp = leftOp ;
this.rightOp = rightOp ;
}
(lo solte sot lo poqe solvoote)
196
// Evaluation of the expression
public double eval()
throws ArithmeticException
{
switch (expressionType) {
case #c# :
return value ;
case #+# :
return leftOp.eval() + rightOp.eval() ;
case #-# :
return leftOp.eval() rightOp.eval() ;
case #*# :
return leftOp.eval() * rightOp.eval() ;
case #/# :
return leftOp.eval() / rightOp.eval() ;
}
return 0.0 ;
}
public void writeTo(PrintWriter printWriter)
throws IOException
{
switch (expressionType) {
case #c# :
printWriter.print(value) ;
break ;
case #+# :
case #-# :
case #*# :
case #/# :
printWriter.print(#(#) ;
leftOp.writeTo(printWriter) ;
printWriter.print(expressionType) ;
rightOp.writeTo(printWriter) ;
printWriter(#)#) ;
break ;
}
}
}
CeLLe mlse en ouvre foncLlonne. Cn auralL programme alnsl dans n'lmporLe quel langage procedural
ou foncLlonnel. Cn reprodulL la programmaLlon classlque eL ceLLe programmaLlon n'a rlen d'orlenLee
ob[eL. Cn ne Llre pas parLl de l'orlenLe ob[eL. CeLLe mlse en euvre foncLlonne mals elle souffre de blen
des defauLs. voyons a presenL ces defauLs.
ltemlet Jfoot
Le comporLemenL d'un ob[eL expresslon depend de l'aLLrlbuL expressionType. C'esL conLralre a
l'un de nos prlnclpes. Cela se LradulL par l'uLlllsaLlon de l'lnsLrucLlon switch dans les meLhodes
eval eL writeTo. La Lallle des lnsLrucLlons swicth esL proporLlonnelle au nombre de Lypes
d'expresslons. Sl nous lnLrodulsons des Lypes d'expresslons supplemenLalres, par exemple x % y
pour le modulo ou sqrt(x) pour la raclne carree, la Lallle des lnsLrucLlon switch va rapldemenL
croiLre au dela du ralsonnable. un bon programmeur orlenLe ob[eL n'ecrlL [amals d'lnsLrucLlons
switch. Les lnsLrucLlons swicth sonL coLeuses en Lemps d'execuLlon sl les valeurs LesLees ne
197
sonL pas consecuLlves. ar allleurs, l'lmplemenLaLlon d'une meLhode dolL Lre enLleremenL vlslble a
l'ecran, ce qul veuL dlre qu'elle ne dolL pas falre plus de 20 llgnes envlron.
ueoxlme Jfoot
ll y a une consommaLlon de memolre lnuLlle. uans le cas ou l'expresslon esL une consLanLe, les
aLLrlbuLs leftOp eL rightOp sonL lnuLlllses. ll exlsLe neanmolns eL dolvenL Lre lnlLlallses. uans le
cas ou l'expresslon esL une expresslon blnalre, le champ valeur esL lnuLlllse. ll exlsLe neanmolns eL
dolL Lre lnlLlallse. Les langages classlques proposenL des Lypes un|on qul permeLLenL de redulre ce
gasplllage sans l'ellmlner LoLalemenL. Ln programmaLlon orlenLe ob[eL, la soluLlon s'appelle le sous-
classemenL.
1tolslme Jfoot
lmaglnons que noLre programme de calculaLrlce foncLlonne blen depuls quelques mols mals que
voLre cllenL deslre un nouveau Lype d'expresslons comme par exemple x % y, le modulo. Cn
lnLrodulra le caracLere #%# pour ce Lype d'expresslon, c'esL-a-dlre pour la valeur
d'expressionType. Le probleme esL qu'ensulLe ll va fallolr modlfler les lnsLrucLlons switch des
meLhodes eval eL writeTo. AuLremenL dlL, nous allons modlfler un code eprouve. LL a, ce n'esL
pas bon !
La programmaLlon n'esL pas une sclence exacLe mals elle esL falLe de meLhodes eL de
paradlgmes eprouves.
Mme avec les mellleures meLhodes de Cenle Loglclel, on n'esL blen lncapable de fournlr un
programme garanLl sans defauL. Alors que les lngenleurs des onLs sonL capable de consLrulre des
ponLs qul ne s'effondrenL pas, la mellleure enLreprlse lnformaLlque ne peuL reellemenL garanLlr son
code. ll y a blen des ralsons Lheorlques eL praLlques a cela. Ln consequence, quand du code esL
eprouve, on heslLe a le modlfler. Cn ne Louche pas a un programme qul foncLlonne.
1S.2.4. La bonne so|ut|on
La bonne soluLlon s'appelle le sous-classemenL :
uans ceL arbre d'herlLage du package expressions, l'lnLerface ExpressionInterface ne
change pas par rapporL a celle que nous avons de[a falL. SolL :
198
package expressions ;
import java.io.* ;
public interface ExpressionInterface
{
public double eval()
throws ArithmeticException ;
public void writeTo(PrintWriter printWriter)
throws IOExcpetion ;
}
La classe absLralLe Expression ne conLlenL rlen. Llle devralL conLenlr ce qul esL commun a LouLes
les expresslons mals cecl esL de[a dans l'lnLerface cl-dessus. Ce sonL ses classes fllles qul
lmplemenLeronL les dlfferenLs Lypes d'expresslons :
package expressions ;
public abstract class Expression
implements ExpressionInterface
{}
La classe Constant deflnlra les expresslons consLanLes :
package expressions ;
import java.io.* ;
public final class Constant extends Expression
{
private final double value ;
public Constant(double value)
{
this.value = value ;
}
public double eval()
{
return value ;
}
public void writeTo(PrintWriter printWriter)
{
printWriter.print(value) ;
}
}
CeLLe classe conLlenL LouLes les meLhodes speclallsees pour les consLanLes. Llle esL declaree final
car aucune classe n'herlLera de ceLLe classe.
La classe sulvanLe esL egalemenL une classe absLralLe. C'esL la classe BinaryExpression qul
conLlenL ce qul esL commun a LouLes les expresslons blnalres, c'esL a dlre les deux operandes eL un
operaLeur. Comme l'operaLeur esL commun a Lous les ob[eLs d'une classe d'expresslon blnalre, nous
ne le meLLrons pas sous forme d'aLLrlbuL mals sous forme de meLhode. Ln effeL, les meLhodes sonL
199
deLenues par la classe Landls que les valeurs des aLLrlbuLs sonL deLenues par les ob[eLs (3.1). CeLLe
classe aura donc une meLhode absLralLe qul fournlra l'operaLeur.
package expressions ;
import java.io.* ;
public abstract class BinaryExpression extends Expression
{
private final Expression leftOp ;
private final Expression rightOP ;
public BinaryExpression(Expression leftOp, Expression rightOp)
{
this.leftOp = leftOp ;
this.rightOp = rightOp ;
}
public abstract String getOperator() ;
public final void writeTo(PrintWriter printWriter)
throws IOException
{
printWriter.print(#(#) ;
leftOp.writeTo(printWriter) ;
printWriter.print(getOperator()) ;
rightOp.writeTo(printWriter) ;
printWriter.print(#)#) ;
}
}
A presenL, la classe Addition esL une concreLlsaLlon de la classe BinaryInterface :
package final Addition extends BinaryExpression
{
public Addition(Expression leftOp, Expression rightOp)
{
super(leftOp,righOp) ;
}
public String getOperator()
{
return "+" ;
}
public double eval()
{
return leftOp.eval() + rightOp.eval() ;
}
}
CeLLe classe esL declaree final car aucune auLre classe n'en herlLera. Cn ne declare pas que la
meLhode eval() peuL produlre une excepLlon. Cn ne declarera cela que donc la meLhode eval()
de la classe Division.
200
La classe Substraction se falL sur le mme modele :
package expressions ;
package final Substraction extends BinaryExpression
{
public Substraction(Expression leftOp, Expression rightOp)
{
super(leftOp,righOp) ;
}
public String getOperator()
{
return "-" ;
}
public double eval()
{
return leftOp.eval() - rightOp.eval() ;
}
}
La classe Product se falL aussl sur le mme modele :
package expressions ;
package final Product extends BinaryExpression
{
public Product(Expression leftOp, Expression rightOp)
{
super(leftOp,righOp) ;
}
public String getOperator()
{
return "*" ;
}
public double eval()
{
return leftOp.eval() * rightOp.eval() ;
}
}
201
La classe Division se falL aussl sur le mme modele. La seule dlfference esL l'excepLlon qul peuL
Lre levee par la meLhode eval :
package expressions ;
package final Division extends BinaryExpression
{
public Division(Expression leftOp, Expression rightOp)
{
super(leftOp,righOp) ;
}
public String getOperator()
{
return "/" ;
}
public double eval()
throws ArithmeticExpression
{
return leftOp.eval() / rightOp.eval() ;
}
}
nous obLenons un arbre d'herlLage plus lmporLanL. lus de llgnes de code dans un premler Lemps
mals le code esL dlsLrlbue dans de peLlLes classes Lres slmples eL Lres faclles a conLrler. Sl un bug se
presenLe, ll sera blen plus faclle de le Lrouver avec ceLLe formulaLlon qu'avec la precedenLe.
1S.2.S. Ltendre avec un nouve| oprateur b|na|re
Avec ceLLe nouvelle formulaLlon, ll esL Lres faclle d'eLendre le code avec un nouvel operaLeur. nous
lmplemenLons la classe Modulo correspondanL a l'operaLlon x % y :
package expressions ;
package final Modulo extends BinaryExpression
{
public Modulo(Expression leftOp, Expression rightOp)
{
super(leftOp,righOp) ;
}
public String getOperator()
{
return "%" ;
}
public double eval()
throws ArithmeticExpression
{
return leftOp.eval() % rightOp.eval() ;
}
}
Ln falL, un nouvelle operaLeur blnalre se falL par une operaLlon de copler-coller.
202
1S.2.6. Ltendre avec des express|ons fonct|onne||es
Supposons malnLenanL que l'on veullle ah-[ouLer des expresslons foncLlonnelles comme sqrt(x) eL
log(x). Sur le mme modele que pour les expresslons blnalres, on a[ouLera une classe
lnLermedlalre absLralLe FunctionalExpression qul conLlenL ce qul esL commun aux
expresslons foncLlonnelles. uls nous creerons les classes Sqrt eL Log.
La classe FunctionalExpression conLlenL ce qul esL commun a LouLes les expresslons
foncLlonnelles :
package expressions ;
import java.io.* ;
public abstract class FunctionalExpression extends Expression
{
private final Expression argument ;
public FunctionalExpression(Expression argument)
{
this.argument = argument ;
}
public abstract String getFunctionName() ;
public final void writeTo(PrintWriter printWriter)
{
printWriter.print(getFunctionName()) ;
printWriter.print(#(#) ;
printWriter.writeTo(printWriter) ;
printWriter.print(#)#) ;
}
}
La classe Sqrt :
package expressions ;
public final class Sqrt extends FunctionalExpression
{
public Sqrt(Expression argument)
{
super(argument) ;
}
public String getFunctionName()
{
return "sqrt" ;
}
public double eval()
throws ArithmeticExpression
{
return Math.sqrt(argument) ;
}
}
203
ue mme la classe Log :
package expressions ;
public final class Log extends FunctionalExpression
{
public Log(Expression argument)
{
super(argument) ;
}
public String getFunctionName()
{
return "log" ;
}
public double eval()
throws ArithmeticExpression
{
return Math.log(argument) ;
}
}
1S.3. our une bonne mod||sat|on
Cn volL que l'a[ouL d'une operaLlon blnalre supplemenLalre dans noLre programme de calculaLrlce a
eLe Lres faclle. Cn a sulvl le paLron (potteto) lnLrodulL prealablemenL.
ue mme l'a[ouL d'un nouveau Lype d'expresslons, les expresslons foncLlonnelles, a eLe lmmedlaL.
nous avons cree la classe absLralLe correspondanLe puls nous avons cree les classes d'expresslons
foncLlonnelles. lcl aussl, nous avons sulvl le paLron (potteto) lnLrodulL prealablemenL.
Sl l'on reflechlL blen, on volL que le developpemenL des expresslons peuL se falre de manlere
lncremenLale alnsl que les LesLs des expresslons de[a developpes.
Cn lmaglne que la recherche de bug sera faclllLee car le code esL dlsLrlbue en peLlLes classes
exLrmemenL slmples. L'a[ouL de nouvelles foncLlonnallLes n'a pas necesslLe de modlflcaLlons du
code exlsLanL.
Les lmposanLs eL lnefflcaces switch du premler code onL eLe remplace par la Lres efflcace llalson
dynamlque de meLhodes, volr secLlon 7.7. Celle-cl, conLralremenL au switch, ne depend pas du
nombre de Lypes d'expresslons.
une bonne modellsaLlon orlenLe ob[eL demande un lnvesLlssemenL prealable.
CependanL, le galn en Lerme de clarLe du code, d'evoluLlvlLe, d'efflcaclLe eL d'alsance
dans le debuggage compense le coL lnlLlal.
ue mme, lorsque l'on cholslL une modellsaLlon orlenLe ob[eL eL que celle-cl s'avere generer des
codes complexes, ll peuL Lre lnLeressanL de LouL repenser eL de reecrlre le code.
1S.4. L'|nterface ou |a c|asse abstra|te
nous avons uLlllse une lnLerface ExpressionInterface. Celle-cl eLalL uLlle au momenL de la
concepLlon afln de deflnlr l'lnLerface de programmaLlon des expresslons. Llle a egalemenL permls aux
dlfferenLs programmeurs de commencer a programmer sans que les expresslons solenL de[a
programmees.
204
CependanL, nous avons apprls que l'on uLlllse les lnLerfaces pluLL pour decrlre des proprleLes
parLagees par un cerLaln nombre d'ob[eLs. LL que l'on uLlllse les classes absLralLes pluLL pour decrlre
l'ldenLlLe d'une classe d'ob[eLs.
uans noLre cas, nous avons uLlllses les deux.
L'uLlllsaLlon d'lnLerfaces esL penallsanLe en Lemps d'execuLlon par rapporL a l'uLlllsaLlon
de classes absLralLes.
uonc, ll esL posslble de supprlmer l'lnLerface ExpressionInterface au proflL de la classe
absLralLe Interface que nous programmons alnsl :
package expressions ;
import java.io.* ;
public abstract class Expression
{
public abstract double eval()
throws ArithmeticException ;
public abstract void writeTo(PrintWriter printWriter)
throws IOException ;
}
Cuand ll s'aglL d'une famllle d'ob[eLs de mme naLure, ll esL preferable, pour des
ralsons d'efflcaclLe, d'ecrlre dlrecLemenL la classe absLralLe que l'lnLerface.
une classe absLralLe ne peuL pas avolr d'lnsLances dlrecLes.
une classe absLralLe esL declaree absLralre :
pour des ralsons Lechnlques : ll y a presence de meLhodes absLralLes que l'on ne peuL pas
lmplemenLer dans ceLLe classe ,
pour des ralsons loglques : on ne veuL pas qu'll exlsLe des lnsLances dlrecLes de ceLLe classe.
Ln general, comme dans le cas de la classe Expression, ces deux ralsons se re[olgnenL.
1S.S. L'extens|on modu|a|re
L'exLenslon modulalre, c'esL :
prendre une classe exlsLanLe ,
deflnlr une classe herlLanL de la premlere ,
l'enrlchlr avec de nouvelles meLhodes.
Cela permeL de :
reuLlllser le code exlsLanL ,
adapLer des classes exlsLanLes.
Conslderons les classes DataOutputStream eL DataInputStream que nous avons de[a
renconLre (9.9). Llles permeLLenL de llre eL d'ecrlre des donnees scalalres en blnalres.
Conslderons malnLenanL la classe Color.
203
renez voLre navlgaLeur prefere eL voLre moLeur de recherche prefere, puls enLrez la
recherche : Java SE7 Color. Cherchez la documenLaLlon de Color.
La classe Color permeL de represenLer une couleur en 8v8 (rouge, verL, bleu).
Supposons qu'en plus des Lypes scalalres, nous voullons sauvegarder des couleurs au formaL 8v8
dans un DataOutputStream de nom out. nous ecrlrlons :
out.write(color.getRed()) ;
out.write(color.getGreen()) ;
out.write(color.getBlue()) ;
Sl nous voulons le rellre dans un DataInputStream de nom in, nous ecrlrlons :
int red = in.readInt() ;
int green = in.readInt() ;
int blue = in.readInt() ;
Color color = new Color(red,green,blue) ;
La quesLlon qul se pose alors esL pourquol ne pas lnLegrer la connalssance des couleurs dans les deux
classes de Joto stteoms ?
uans le cas du DataOutputStream, cela donneralL MyDataOutputStream :
public class MyDataOutputSTream extends DataOutputStream
{
public final void write(Color color)
{
write(color.getRed()) ;
write(color.getGreen()) ;
write(color.getBlue()) ;
}
}
uans le cas de DataInputStream, cela donneralL MyDataInputStream :
public class MyDataInputStream extends DataInputStream
{
public final Color readColor()
{
int red = in.readInt() ;
int green = in.readInt() ;
int blue = in.readInt() ;
return new Color(red,green,blue) ;
}
}
206
Ln aglssanL alnsl, nous avons apporLe une nouvelle foncLlonnallLe aux Joto stteoms : la
posslblllLe de LralLer les couleurs.
ll esL bon de proceder alnsl. Cn possede une nouve||e c|asse qul elle-mme pourra Lre reuLlllsee eL
eLendue. Sl l'on deslre changer le codage des couleurs dans le flchler blnalre, ll n'y aura que deux
meLhodes a reLoucher.
1S.6. Approche pro[et
Les a|gor|thmes. uans le cadre d'un pro[eL !ava, ll fauL blen sr lmaglner le ou les algorlLhmes qul
vonL alder a resoudre le probleme.
Les ob[ets. uls, ll fauL ldenLlfler les dlfferenLs Lypes d'ob[eLs mls en [eu. ues seances de Lravall en
groupe sonL adapLees :
ll y a les vrals ob[eLs qul sonL vlslbles eL evldenLs : les elemenLs de l'lnLerface graphlque, les
elemenLs nommes dans le su[eL, eLc.
ll y a les elemenLs un peu plus absLralLs qul n'apparalssenL pas forcemenL comme des ob[eLs :
une connexlon enLre deux [oueurs, les messages echanges, eLc.
ll y a les ob[eLs lles a l'lmplemenLaLlon : une memolre globale, des appels aux foncLlons
sysLemes porLes par des ob[eLs, eLc.
Ce Lravall dolL Lre falL en profondeur avanL l'ecrlLure de la premlere llgne de !ava.
Les packages. 1ou[ours en groupe, ll fauL deLermlner les packages de voLre programme avec
evenLuellemenL des sous-packages. ll fauL blen dellmlLer ce qul dolL Lre vlslble de l'exLerleur du
packages.
Les |nterfaces. Cn ecrlra les lnLerfaces de programmaLlon commenLees eL on uLlllsera de manlere
approprlee les moLs cles public, protected eL private. ar exemple, dans le cas d'une
connexlon reseau, ne seronL vlslbles que la classe qul represenLe la connexlon reseau eL les classes
des dlfferenLs Lypes de messages qu'elle peuL supporLer.
Le ou |es arbres d'hr|tage. Ln groupe, ll fauL fabrlquer le ou les arbres d'herlLage :
Commencer par la raclne eL falre du sous-classemenL.
8len uLlllser les lnLerfaces eL les classes absLralLes.
8len rechercher ce qul exlsLe de[a en !ava eL falre de l'exLenslon modulalre.
kespecter |es rg|es s|mp|es. Cue nous avons de[a vues :
ne pas Lravalller sur ob[eL depuls l'exLerleur de l'ob[eL, demander a l'ob[eL de falre le Lravall
lul-mme (prlnclpe de non lnLruslon).
un ob[eL qul a un Lravall a falre dolL essayer, sl c'esL ralsonnable, de deleguer le Lravall a
d'auLres ob[eLs (prlnclpe de delegaLlon).
roLeger les aLLrlbuLs qul dolvenL Lre declares private (prlnclpe d'encapsulaLlon).
La programmat|on. Cn se reparLlL les packages dans le groupe. Sl le Lravall precedenL a eLe blen falL,
on pourra programmer sans probleme. Cn pourra egalemenL reallser des modlflcaLlons dans la
concepLlon sans Lrop de problemes.
Intgrer. 8assembler les packages. Sl le Lravall precedenL a eLe blen falL, cela peuL aller Lres vlLe.
Cpt|m|ser. MeLLre les moLs cles final oublles sur les classes, les meLhodes eL les aLLrlbuLs.
Supprlmer les lnLerfaces de programmaLlon qul ne servenL a rlen comme ExpressionInterface
dans noLre exemple des expresslons.
207
1S.7. Dern|er conse||s
endanL la phase de concepLlon, ne pas heslLer a uLlllser le langage graphlque uML (uolfleJ
MoJelloq looqooqe). ll exlsLe des edlLeurs uML graLulL. Le langage graphlque d'uML que nous avons
vu dans cerLalns graphlques permeL d'alder a la modellsaLlon de voLre probleme.
ll n'exlsLe pas de meLhodes de concepLlon parfalLe en LouL lleu eL a LouLe heure. ne pas heslLer a
recommencer encore eL encore la concepLlon de voLre programme [usqu'a ce que LouL solL ob[eL,
[usqu'a ce que LouL s'emboiLe naLurellemenL eL sans arLlflce compllque.
ll y a un apprenLlssage a falre. 8eaucoup d'enLrainemenL esL necessalre. LL ll fauL arrlver a oubller les
manleres de programmer venues d'allleurs.
208