Académique Documents
Professionnel Documents
Culture Documents
Informatique
Faculté des Sciences
Université Mohammed Premier
Oujda
Filière : SMI
Semestre : 5
1 Introduction à Java 1
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 La plateforme Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3 Premier programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3.1 Installation sous Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.2 Installation sous Windows . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.3 Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.4 Exécution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Description du premier programme . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.1 Déclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.2 Première classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.3 Méthode main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 Commentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6 Données primitifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.1 Types numériques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6.2 Caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6.3 Type boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6.4 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.7 Expressions et opérateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Classes et objets 9
2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Déclaration d'une classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1 Dénition des attributs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.2 Dénition des méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3 Utilisation des classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.4 Initialisation des objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
i
2.5 Portée des attributs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6 Surcharge des méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6.1 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6.2 Utilisation de la classe Etudiant . . . . . . . . . . . . . . . . . . . . . . . 13
2.6.3 Conit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.7 Lecture à partir du clavier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3 Constructeurs 18
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2 Dénition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3 Utilisation de this . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.4 Surcharge des constructeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.5 Constructeur par défaut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.6 Constructeur de copie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4 Héritage 24
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2 Exemple introductif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.3 Utilisation de l'héritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.4 Accès aux attributs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.5 Héritage hiérarchique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6 Masquage et redénition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6.1 Dénitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6.2 Exemple : masquage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.6.3 Exemples : redénition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.7 Héritage et constructeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.7.1 Exemple 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.7.2 Exemple 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.7.3 Exemple 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.8 Opérateur instanceof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5 Chaînes de caractères 35
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2 Manipulation des caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.3 La classe String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.3.1 Déclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
ii
5.3.2 Remarques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.3.3 Méthodes de traitement des chaînes de caractères . . . . . . . . . . . . . 37
5.3.4 Conversion entre String et types primitifs . . . . . . . . . . . . . . . . . . 40
5.4 Achage des objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.5 Comparaison des objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.6 Les classes StringBuilder et StringBuer . . . . . . . . . . . . . . . . . . . . . . 42
5.6.1 Déclaration et création . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.6.2 Méthodes de StringBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6 Tableaux 45
6.1 Déclaration et initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.2 Déclaration mixte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
6.3 Taille d'un tableau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
6.4 Parcours d'un tableau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
6.5 Copie de tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
6.5.1 Utilisation de : System.arraycopy() . . . . . . . . . . . . . . . . . . . . . 48
6.5.2 Utilisation de : Arrays.copyOf() ou Arrays.copyOfRange() . . . . . . . . 49
6.6 Comparer le contenu de deux tableaux de types primitifs . . . . . . . . . . . . . 49
6.7 Utilisation de la classe Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.7.1 Trie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.7.2 Recherche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.7.3 Remplissage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
6.7.4 Méthode toString() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
6.8 Passage et retour d'un tableau dans une méthode . . . . . . . . . . . . . . . . . 52
6.9 Passage d'un tableau dans une méthode . . . . . . . . . . . . . . . . . . . . . . 52
6.10 Retour d'un tableau dans une méthode . . . . . . . . . . . . . . . . . . . . . . . 53
6.11 Tableaux d'objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.12 Objets qui contiennent des tableaux . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.13 Tableaux à plusieurs dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.13.1 Parcours d'un tableau multi-dimensionnel . . . . . . . . . . . . . . . . . 57
6.13.2 Initialisation au début . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
7 Généralités 59
7.1 Attributs statiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
7.1.1 Constantes nal et static . . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.2 Méthodes statiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
iii
7.3 Méthodes nales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.4 Classes nales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.5 Fin de vie des objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
7.6 Ramasse miettes (Garbage collector) . . . . . . . . . . . . . . . . . . . . . . . . 63
8 Polymorphisme et abstraction 64
8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
8.2 Exemple introductif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
8.3 Liaison dynamique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
8.4 Méthodes de classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
8.4.1 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
8.5 Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
8.5.1 Exemples introductifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
8.5.2 Constructeurs et abstraction . . . . . . . . . . . . . . . . . . . . . . . . . 70
8.5.3 Remarque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
9 Interfaces et packages 72
9.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
9.2 Déclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
9.3 Règles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
9.4 Implémenter une interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
9.4.1 Implémentation partielle . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
9.4.2 Implémentation multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
9.4.3 Implémentation et héritage . . . . . . . . . . . . . . . . . . . . . . . . . . 75
9.5 Polymorphisme et interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
9.5.1 Déclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
9.5.2 Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
9.5.3 Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
9.6 Héritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
9.7 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
9.7.1 Création d'un package . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
9.7.2 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
9.7.3 Classes du même package . . . . . . . . . . . . . . . . . . . . . . . . . . 79
9.7.4 Fichiers jar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
iv
10.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
10.2 Gestion des erreurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
10.3 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
10.3.1 classe Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
10.3.2 classe Exception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
10.4 Types d'exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
10.5 Méthodes des exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
10.6 Capture des exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
10.7 Utilisation du bloc try-catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
10.7.1 Un seul catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
10.7.2 plusieurs catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
10.7.3 Bloc nally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
10.7.4 Blocs try imbriqués . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
10.8 Exceptions personnalisées . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
10.8.1 Gestion d'une seule exception . . . . . . . . . . . . . . . . . . . . . . . . 90
10.8.2 Gestion de plusieurs exceptions . . . . . . . . . . . . . . . . . . . . . . . 91
10.9 Spécier l'exception qu'une méthode peut générer . . . . . . . . . . . . . . . . . 92
v
Chapitre 1
Introduction à Java
1.1 Introduction
Les langages orientés objets prennent en charge les quatre caractéristiques importantes sui-
vantes :
Encapsulation
Abstraction
Héritage
Polymorphisme
1
}
Le programme doit être enregistré (obligatoirement) dans un chier portant le même nom
que celui de la classe Bonjour.java.
Pour compiler le programme précédent, il faut tout d'abord installer l'environnement de déve-
loppement JDK (Java Developpment Kit).
PATH=~/jdk1.7.0_xy/bin:$PATH
C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Java\jdk1.7.0_xy\bin
2
1.3.3 Compilation
Dans une console, déplacez vous dans le répertoire ou se trouve votre chier et tapez la com-
mande suivante :
javac Bonjour.java
Après la compilation et si votre programme ne comporte aucune erreur, le chier Bonjour.class
sera généré.
1.3.4 Exécution
Il faut exécuté le chier .class en tapant la commande (sans extension) :
java Bonjour
Après l'exécution, le message suivant sera aché.
Bonjour - SMI-S5
3
abstract continue for new switch
assert default goto package synchronized
boolean do if private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char nal interface static void
class nally long strictfp volatile
const oat native super while
Table 1.1 mots clés
En java, il est, par convention, souhaitable de commencer les noms des classes par une lettre
majuscule et utiliser les majuscules au début des autres noms pour agrandir la lisibilité des
programmes.
La table 1.2 contient quelques mots qui peuvent être utilisés comme noms de classes. La table
1.3 contient quelques mots qui peuvent être utilisés comme noms de classes mais ne sont pas
recommandés. Si vous utilisez un de ces mots, la compilation se passe sans problème. La table
1.4 contient quelques mots qui ne peuvent pas être utilisés comme noms de classes.
4
Nom de la classe description
Etudiant# contient #
double mot réservé
Prix Produit contient un espace
2014annéescolaire commence par un chire
Table 1.4 Quelques noms de classes non valides
String est une classe. Les crochets ([]) indiquent que args est un tableau (voir plus loin
pour plus d'informations sur l'utilisation des tableaux).
Le mot clés void, désigne le type de retour de la méthode main(). Il indique que main()
ne retourne aucune valeur lors de son appel.
Le mot clés static indique que la méthode est accessible et utilisable même si aucun
objet de la classe n'existe.
Le mot clés public sert à dénir les droits d'accès. Il est obligatoire dans l'instruction
public static void main(String[] args) et peut être omis dans la ligne public class
Bonjour.
1.5 Commentaires
Les commentaires peuvent s'écrire sur une seule ligne ou sur plusieurs ligne, comme dans
l'exemple suivant :
/*
Premier programme en Java
c o n t i e n t une s e u l e c l a s s e avec une s e u l e methode
*/
p u b l i c c l a s s Bonjour {
// methode p r i n c i p a l e
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
System . out . p r i n t l n ( " Bonjour − SMI−S5" ) ;
}
}
5
de la compilation (contrairement au langage C) indiquant que la variable n'est pas initialisée
(The local variable age may not have been initialized).
Remarques :
1. Par défaut, une valeur comme 3.14 est de type double, donc pour l'aecter à une variable
de type oat, il faut la faire suivre par la lettre f (majuscule ou minuscule).
float pi=3.14F, min=10.1f;
2. Par défaut les entiers sont de type int. Pour aecter une valeur inférieure à −2 147
483 648 ou supérieure à 2 147 483 647 à un long, il faut la faire suivre par la lettre l
(majuscule ou minuscule).
long test=4147483647L;
1.6.2 Caractères
On utilise le type char pour déclarer un caractère. Par exemple :
char c= ' a ' ;
char e t o i l e= ' * ' ;
Les caractères sont codés en utilisant l'unicode. Ils occupent 2octets en mémoire. Ils permettent
de représenter 65536 caractères, ce qui permet de représenter (presque) la plupart des symboles
utilisés dans le monde. Dans la table 1.6, on retrouve quelques séquences d'échappement.
6
Séquence d'échappement Description
\n nouvelle ligne (new line)
\r retour à la ligne
\b retour d'un espace à gauche
\\ \ (back slash)
\t tabulation horizontale
\' apostrophe
\" guillemet
Table 1.6 Séquences d'échappement
1.6.4 Constantes
Pour déclarer une constante, il faut utiliser le mot clés nal. Par convention, les constantes
sont écrites en majuscule.
Exemple :
f i n a l i n t MAX = 1 0 0 ;
f i n a l double PI = 3 . 1 4 ;
...
f i n a l i n t MAX_2 = MAX * MAX;
max = b ;
min = a ;
i f (a > b) {
max = a ;
min = b ;
}
// E q u i v a l e n t a p r i n t f du l a n g a g e C
System . out . p r i n t f ( "max = %f \ tmin =%f \n" , max , min ) ;
// C a r r e e s des nombres i m p a i r s de 1 a 30
f o r ( i n t i =1; i <=30; i +=2)
System . out . p r i n t f ( "%d^2 = %d\n" , i , i * i ) ;
7
}
}
8
Chapitre 2
Classes et objets
2.1 Introduction
comme mentionné au chapitre précédent, Java est un langage (presque) purement orientée
objets. Tout doit être à l'intérieure d'une classe.
Remarques :
1. on peut dénir plusieurs classes dans un même chier à condition qu'une seule classe soit
précédée du mot clés public et que le chier porte le même nom que la classe publique ;
2. une classe peut exister dans un chier séparé (qui porte le même nom suivi de .java) ;
3. pour que la machine virtuelle puisse accéder à une classe contenant la méthode main, il
faut que cette classe soit publique.
9
c l a s s Etudiant {
private String nom ;
private String prenom ;
private String cne ;
p r i v a t e double moyenne
}
Par convention, les noms des attributs et des méthodes doivent être en minuscule. Le pre-
mier mot doit commencer en minuscule et les autres mots doivent commencer en majuscule
(ceciEstUneVariable, ceciEstUneMethode).
Remarque : la présence du mot clés private (privé) indique que les variables ne seront pas ac-
cessibles de l'extérieure de la classe où elles sont dénies. C'est possible de déclarer les variables
non privé, mais c'est déconseillé.
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
p r i v a t e double moyenne ;
// I n i t i a l i s e r l e s i n f o r m a t i o n s c o nc e r na n t l ' e t u d i a n t
p u b l i c void i n i t i a l i s e r ( S t r i n g x , S t r i n g y , S t r i n g z , double m) {
nom = x ;
prenom = y ;
cne = z ;
moyenne = m;
}
// A f f i c h a g e des i n f o r m a t i o n s c o nc e r n an t l ' e t u d i a n t
p u b l i c void a f f i c h e r ( ) {
System . out . p r i n t l n ( "Nom : "+nom ) ;
System . out . p r i n t l n ( "Prenom : "+prenom ) ;
System . out . p r i n t l n ( "CNE : "+cne ) ;
System . out . p r i n t l n ( "Moyenne : "+moyenne ) ;
}
// r e t o u r n e r l a moyenne
p u b l i c double getMoyenne ( ) {
r e t u r n moyenne ;
}
}
10
Remarques :
On peut dénir plusieurs méthodes à l'intérieure d'une classe.
La présence du mot clés public (publique) indique que les méthodes sont accessibles de
l'extérieure de la classe. C'est possible de déclarer des méthodes privés.
Il existe d'autres modes d'accès aux variables et aux méthodes qu'on verra plus loin.
Exemple :
Dans l'exemple suivant, on va utiliser la classe ExempleEtudiant, pour tester la classe
Etudiant :
p u b l i c c l a s s ExempleEtudiant {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
double moy ;
Etudiant e t = new Etudiant ( ) ;
e t . i n i t i a l i s e r ( " Oujdi " , "Mohammed" , "A8899" , 1 2 . 5 ) ;
et . a f f i c h e r ( ) ;
e t . i n i t i a l i s e r ( " Berkani " , "Ahmed" , "A7788" , 1 3 ) ;
moy = e t . getMoyenne ( ) ;
System . out . p r i n t l n ( "Moyenne : "+moy ) ;
}
}
c l a s s Etudiant {
...
}
11
Exécution :
Le résultat de l'exécution du programme précédent est le suivant :
Nom : Oujdi
Prenom : Mohammed
CNE : A8899
Moyenne : 12.5
Moyenne : 13.0
Type boolean char byte short int long oat double objet
valeur par false '\u0000' (byte)0 (short)0 0 0L 0.0f 0.0 null
défaut
Table 2.1 Valeurs par défaut des attributs d'un objet
2.6.1 Exemple
On va ajouter à la classe Etudiant trois méthodes qui portent le même nom. Une méthode
qui contient :
12
1. trois arguments de types double ;
2. deux arguments de types double ;
3. deux arguments de types oat.
c l a s s Etudiant {
...
// c a l c u l de l a moyenne de t r o i s nombres
p u b l i c double calculMoyenne ( double m1, double m2, double m3) {
double moy ;
moy = (m1+m2+m3) / 3 ;
r e t u r n moy ;
}
13
p u b l i c c l a s s ExempleEtudiant {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
double moy ;
Etudiant e t = new Etudiant ( ) ;
e t . i n i t i a l i s e r ( " Oujdi " , "Mohammed" , "A8899" , 1 2 . 5 ) ;
2.6.3 Conit
Considérons la classe Etudiant qui contient deux méthodes. Une méthode qui contient :
1. deux arguments, un de type double et l'autre de type oat ;
2. deux arguments, un de type oat et l'autre de type double.
c l a s s Etudiant {
...
p u b l i c double calculMoyenne ( double m1, f l o a t m2) {
double moy ;
moy = (m1+m2) / 2 ;
r e t u r n moy ;
}
14
Exemple d'utilisation
p u b l i c c l a s s ExempleEtudiant {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
double moy ;
Etudiant e t = new Etudiant ( ) ;
e t . i n i t i a l i s e r ( " Oujdi " , "Mohammed" , "A8899" , 1 2 . 5 ) ;
// 1 1 . 5 e t 1 3 . 5 s o n t de type double
// Erreur de c o m p i l a t i o n
moy = e t . calculMoyenne ( 1 1 . 5 , 1 3 . 5 ) ;
// 1 1 . 5 f e t 1 3 . 5 f s o n t de type f l o a t
// Erreur de c o m p i l a t i o n
moy = e t . calculMoyenne ( 1 1 . 5 f , 1 3 . 5 f ) ;
}
}
15
Exemple :
import j a v a . u t i l . Scanner ;
p u b l i c c l a s s TestScanner
{
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s )
{
S t r i n g nom ;
i n t age ;
double note1 , note2 , moyenne ;
// c l a v i e r e s t un o b j e t qui va p e r m e t t r e l a s a i s i e c l a v i e r
// vous pouvez u t i l i s e r un a u t r e nom ( keyb , input , . . . )
Scanner c l a v i e r = new Scanner ( System . i n ) ;
System . out . p r i n t ( " S a i s i r v o t r e nom : " ) ;
nom = c l a v i e r . nextLine ( ) ;
System . out . p r i n t ( " S a i s i r v o t r e age : " ) ;
age = c l a v i e r . n e x t I n t ( ) ;
System . out . p r i n t ( " S a i s i r vos n o t e s : " ) ;
note1 = c l a v i e r . nextDouble ( ) ;
note2 = c l a v i e r . nextDouble ( ) ;
moyenne = ( note1+note2 ) / 2 ;
System . out . p r i n t l n ( " Votre nom e s t " + nom + " , vous avez "
+ age + " ans e t vous avez obtenu "+ moyenne ) ;
c l a v i e r . c l o s e ( ) ; // f e r m e r l e Scanner
}
}
16
import j a v a . u t i l . Scanner ;
p u b l i c c l a s s TestScanner
{
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s )
{
S t r i n g nom ;
i n t age ;
double note1 , note2 , moyenne ;
Scanner c l a v i e r = new Scanner ( System . i n ) ;
System . out . p r i n t ( " S a i s i r v o t r e age : " ) ;
age = c l a v i e r . n e x t I n t ( ) ;
System . out . p r i n t ( " S a i s i r v o t r e nom : " ) ;
nom = c l a v i e r . nextLine ( ) ;
System . out . p r i n t ( " S a i s i r vos n o t e s : " ) ;
note1 = c l a v i e r . nextDouble ( ) ;
note2 = c l a v i e r . nextDouble ( ) ;
moyenne = ( note1+note2 ) / 2 ;
System . out . p r i n t l n ( " Votre nom e s t " + nom + " , vous avez "
+ age + " ans e t vous avez obtenu "+ moyenne ) ;
}
}
Lors de la saisie de l'age, on a validé par Entrée . La touche Entrée a été stocké dans nom !
Pour éviter ce problème, il faut mettre clavier.nextLine() avant nom = clavier.nextLine();
(listing 2.1).
p u b l i c c l a s s TestScanner
{
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s )
{
...
age = c l a v i e r . n e x t I n t ( ) ;
System . out . p r i n t ( " S a i s i r v o t r e nom : " ) ;
c l a v i e r . nextLine ( ) ;
nom = c l a v i e r . nextLine ( ) ;
...
}
}
Listing 2.1 test
17
Chapitre 3
Constructeurs
3.1 Introduction
On a vu dans le chapitre 2, que pour initialiser les attributs de la classe Etudiant, on a dénit
une méthode initialiser().
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
p r i v a t e double moyenne ;
// I n i t i a l i s e r l e s i n f o r m a t i o n s c o nc e r na n t l ' e t u d i a n t
p u b l i c void i n i t i a l i s e r ( S t r i n g x , S t r i n g y , S t r i n g z , double m) {
nom = x ;
prenom = y ;
cne = z ;
moyenne = m;
}
...
}
Cette façon de faire n'est pas conseillé pour les raisons suivantes :
pour chaque objet créé, on doit l'initialisé en appelant la méthode d'initialisation ;
si on oublie d'initialiser l'objet, il sera initialisé par défaut, ce qui peut poser des pro-
blèmes lors de l'exécution du programme. Du fait que le programme sera compilé sans
erreurs.
Pour remédier à ces inconvénients, on utilise les constructeurs.
3.2 Dénition
Un constructeur est une méthode, sans type de retour, qui porte le même nom que la classe.
Il est invoqué lors de la déclaration d'un objet.
Une classe peut avoir plusieurs constructeurs (surcharge), du moment que le nombre d'argu-
ments et leurs types n'est pas le même.
18
Exemple
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
p r i v a t e double moyenne ;
// C o n s t r u c t e u r
p u b l i c Etudiant ( S t r i n g x , S t r i n g y , S t r i n g z , double m) {
nom = x ;
prenom = y ;
cne = z ;
moyenne = m;
}
...
}
Exemple
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
p r i v a t e double moyenne ;
// C o n s t r u c t e u r
p u b l i c Etudiant ( S t r i n g nom , S t r i n g prenom , S t r i n g cne ,
double moyenne ) {
t h i s . nom = nom ;
t h i s . prenom = prenom ;
t h i s . cne = cne ;
t h i s . moyenne = moyenne ;
}
...
}
19
this.nom, this.prenom, this.cne et this.moyenne correspondent aux attributs de la classe.
Exemple 1
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
p r i v a t e double moyenne ;
// C o n s t r u c t e u r 1
p u b l i c Etudiant ( S t r i n g nom , S t r i n g prenom , S t r i n g cne ) {
t h i s . nom = nom ;
t h i s . prenom = prenom ;
t h i s . cne = cne ;
}
// C o n s t r u c t e u r 2
p u b l i c Etudiant ( S t r i n g nom , S t r i n g prenom , S t r i n g cne ,
double moyenne ) {
t h i s . nom = nom ;
t h i s . prenom = prenom ;
t h i s . cne = cne ;
t h i s . moyenne = moyenne ;
}
...
}
p u b l i c c l a s s ExempleEtudiant {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Etudiant e t = new Etudiant ( " Oujdi " , "Mohammed" , "A8899" , 1 2 . 5 ) ;
20
Exemple 2
Dans le constructeur 2 de l'exemple 1, trois instructions ont été répétées. Pour éviter cette
répétition, on utilise l'instruction this(arguments). L'exemple 1 devient :
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
p r i v a t e double moyenne ;
// C o n s t r u c t e u r 1
p u b l i c Etudiant ( S t r i n g nom , S t r i n g prenom , S t r i n g cne ) {
t h i s . nom = nom ;
t h i s . prenom = prenom ;
t h i s . cne = cne ;
}
// C o n s t r u c t e u r 2
p u b l i c Etudiant ( S t r i n g nom , S t r i n g prenom , S t r i n g cne ,
double moyenne ) {
// Appel du c o n s t r u c t e u r 1
t h i s (nom , prenom , cne ) ;
t h i s . moyenne = moyenne ;
}
...
}
21
Exemple
p u b l i c c l a s s ExempleEtudiant {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
// U t i l i s a t i o n du c o n s t r u c t e u r par défaut
Etudiant e t = new Etudiant ( ) ;
}
}
c l a s s Etudiant {
...
// C o n s t r u c t e u r par d e f a u t
p u b l i c Etudiant ( ) {
nom = "" ;
prenom = "" ;
cne = "" ;
moyenne = 0 . 0 ;
}
// Autres c o n s t r u c t e u r s
...
}
Remarques :
1. Si aucun constructeur n'est utilisé, le compilateur initialise les attributs aux valeurs par
défaut.
2. Dans les exemples 1 et 2 de la section 3.4, l'instruction Etudiant et = new Etudiant();
n'est pas permise parce que les deux constructeurs ont des arguments.
3. Un constructeur ne peut pas être appelé comme les autres méthodes. L'instruction
et.Etudiant("Oujdi","Mohammed","A8899"); n'est pas permise.
22
Exemple
p u b l i c c l a s s ExempleEtudiant {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Etudiant e t 1 = new Etudiant ( " Oujdi " , "Mohammed" , "A8899" ) ;
Etudiant e t 2 = new Etudiant ( e t 1 ) ;
}
}
c l a s s Etudiant {
...
// C o n s t r u c t e u r de c o p i e
p u b l i c Etudiant ( Etudiant autreEt ) {
nom = autreEt . nom ;
prenom = autreEt . prenom ;
cne = autreEt . cne ;
moyenne = autreEt . moyenne ;
}
...
}
Remarque
et1 et et2 sont diérents mais ont les mêmes valeurs pour leurs attributs.
23
Chapitre 4
Héritage
4.1 Introduction
Comme pour les pour autres langages orientés objets, Java permet la notion d'héritage, qui
permet de créer de nouvelles classes à partir d'autres classes existantes. L'héritage permet de
réutiliser des classes déjà dénies en adaptant les attributs et les méthodes (par ajout et/ou
par modication).
Une classe qui hérite d'une classe existante est appelée classe dérivée. Elle est aussi appelée
sous-classe ou classe-lle.
La classe, dont hérite d'autres classes, est appelée classe super-classe. Elle est aussi appelée
classe-mère ou classe-parente.
Syntaxe
class SousClasse extends SuperClass
Remarques :
Java ne permet pas l'héritage multiple. C'est-à-dire, une classe ne peut pas hériter de
plusieurs classes. Elle ne peut hériter que d'une seule classe.
Une classe peut hériter d'une classe dérivée. Considérons la classe A qui est la super-
classe de B et B qui est la super-classe de C. A est la super-super-classe de C.
24
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
void a f f i c h e r ( ) {
System . out . p r i n t l n ( "Nom : "+nom ) ;
System . out . p r i n t l n ( "Prenom : "+prenom ) ;
}
void setNom ( S t r i n g nom){
t h i s . nom = nom ;
}
}
class Professeur {
p r i v a t e S t r i n g nom , prenom , c i n ;
void a f f i c h e r ( ) {
System . out . p r i n t l n ( "Nom : "+nom ) ;
System . out . p r i n t l n ( "Prenom : "+prenom ) ;
}
void setNom ( S t r i n g nom){
t h i s . nom = nom ;
}
void s e t C i n ( S t r i n g c i n ){
this . cin = cin ;
}
}
Listing 4.1 Classes Etudiant et professeur
c l a s s Personne {
p r i v a t e S t r i n g nom , prenom ;
void a f f i c h e r ( ) {
System . out . p r i n t l n ( "Nom : "+nom ) ;
System . out . p r i n t l n ( "Prenom : "+prenom ) ;
}
void setNom ( S t r i n g nom){
t h i s . nom = nom ;
}
}
Listing 4.2 Classe Personne
25
Les deux classes peuvent être modiées en utilisant la classe Personne . Elle deviennent comme
le montre le listing 4.3 suivant :
c l a s s Etudiant e xt e n ds Personne {
p r i v a t e S t r i n g cne ;
void setCne ( S t r i n g cne ){
t h i s . cne = cne ;
}
}
c l a s s P r o f e s s e u r ex t e n ds Personne {
private String cin ;
void s e t C i n ( S t r i n g c i n ){
this . cin = cin ;
}
}
Listing 4.3 Classes Professeur et Etudiant héritent de la classe Personne
c l a s s Etudiant e xt e n ds Personne {
p r i v a t e S t r i n g cne ;
S t r i n g getNom ( ) {
r e t u r n nom ; // non permise
}
}
Exemple
Dans le listing 4.4, la classe Etudiant peut accéder à l'attribut nom puisqu'il est protégé.
26
c l a s s Personne {
p r o t e c t e d S t r i n g nom ;
...
}
c l a s s Etudiant e xt e n ds Personne {
...
S t r i n g getNom ( ) {
r e t u r n nom ;
}
}
Listing 4.4 Accès protégé aux attributs
Remarques :
1. Un attribut protégé est accessible par toutes les sous-classes et par toutes les classes du
même paquetage (on verra plus loin la notion de package) ce qui casse l'encapsulation.
2. Le mode protégé n'est pas très utilisé en Java.
c l a s s Personne {
...
}
c l a s s Etudiant e xt e n ds Personne {
...
}
c l a s s EtudiantEtranger ex t e n ds Etudiant {
private String nationalite ;
...
}
Listing 4.5 EtudiantEtranger hérite de Etudiant et Etudiant
hérite de Personne
27
Redénition (overriding) : comme pour le cas de surcharge à l'intérieure d'une
classe, une méthode déjà dénie dans une super-classe peut avoir une nouvelle dénition
dans une sous-classe (listings 4.7 et 4.8).
Remarques :
1. Il ne faut pas confondre surcharge et redénition !
2. On verra plus de détails concernant la redénition dans le chapitre concernant le poly-
morphisme.
private int a ;
p u b l i c void s e t V a l e u r ( )
{
a = 10;
}
p u b l i c void a f f i c h e ( )
{
// A t t r i b u t g l o b a l de l a c l a s s e
System . out . p r i n t l n ( "a = " + a ) ;
}
p u b l i c void v a r i a b l e L o c a l ( )
{
i n t a = 2 0 ; // v a r i a b l e l o c a l e
System . out . p r i n t l n ( "a = " + a ) ;
}
}
Listing 4.6 Masquage d'une variable
28
4.6.3 Exemples : redénition
Exemple 1
class A
{
p u b l i c void f ( i n t a , i n t b )
{
// i n s t r u c t i o n s
}
// Autres methodes e t a t t r i b u t s
}
c l a s s B e x t e nd s A
{
p u b l i c void f ( i n t a , i n t b )
{
// l a methode r e d i f i n i e f ( ) de l a super − c l a s s e
}
// Autres methodes e t a t t r i b u t s
}
Listing 4.7 Redénition de la méthode f()
Exemple 2
Reprenons l'exemple du listing 4.5 et ajoutons à la classe Personne la méthode acher()
qui permet d'acher le nom et le prénom. Dans les classes Etudiant, EtudiantEtranger,
et Professeur, la méthode acher() peut être dénie avec le même nom et sera utilisé pour
acher les informations propres à chaque classe. Pour ne pas répéter les instructions se trouvant
dans la méthode de base, il faut utiliser le mot clés super() (listing 4.8).
c l a s s Personne {
p r i v a t e S t r i n g nom , prenom ;
void a f f i c h e r ( ) {
System . out . p r i n t l n ( "Nom : "+nom ) ;
System . out . p r i n t l n ( "Prenom : "+prenom ) ;
}
...
}
c l a s s Etudiant e xt e n ds Personne {
p r i v a t e S t r i n g cne ;
void a f f i c h e r ( ) {
super . a f f i c h e r ( ) ;
System . out . p r i n t l n ( "CNE : "+cne ) ;
}
29
...
}
c l a s s EtudiantEtranger ex t e n ds Etudiant {
private String nationalite ;
void a f f i c h e r ( ) {
super . a f f i c h e r ( ) ;
System . out . p r i n t l n ( " N a t i o n a l i t e : "+n a t i o n a l i t e ) ;
}
...
}
c l a s s P r o f e s s e u r ex t e n ds Personne {
private String cin ;
void a f f i c h e r ( ) {
super . a f f i c h e r ( ) ;
System . out . p r i n t l n ( "CIN : "+c i n ) ;
}
...
}
Listing 4.8 Redénition de la méthode acher()
Remarques :
1. La méthode super.acher() doit être la première instruction dans la méthode super.acher().
2. La méthode super.acher() de la classe EtudiantEtranger, fait appel à acher()
de la classe Etudiant.
3. Si la classe Etudiant n'avait pas la méthode acher(), alors, par transitivité, la méthode
super.acher() de la classe EtudiantEtranger, fait appel à acher() de la classe
Personne.
4. Il n'y a pas de : super.super.
4.7.1 Exemple 1
Reprenons l'exemple du listing 4.5 et ajoutons à la classe Personne un seul constructeur.
Si aucun constructeur n'est déni dans les classes Etudiant et Professeur, il y aura erreur de
compilation (listing 4.9).
c l a s s Personne {
p r i v a t e S t r i n g nom , prenom ;
30
// C o n s t r u c t e u r
p u b l i c Personne ( S t r i n g nom , S t r i n g prenom ) {
t h i s . nom = nom ;
t h i s . prenom = prenom ;
}
...
}
c l a s s Etudiant e xt e n ds Personne {
...
p r i v a t e S t r i n g cne ;
// Pas de c o n s t r u c t e u r
...
}
c l a s s P r o f e s s e u r ex t e n ds Personne {
...
p r i v a t e S t r i n g cne ;
// Pas de c o n s t r u c t e u r
...
}
Listing 4.9 Héritage et constructeurs
4.7.2 Exemple 2
c l a s s Personne {
p r i v a t e S t r i n g nom , prenom ;
// C o n s t r u c t e u r
p u b l i c Personne ( S t r i n g nom , S t r i n g prenom ) {
t h i s . nom = nom ;
t h i s . prenom = prenom ;
}
...
}
c l a s s Etudiant e xt e n ds Personne {
...
p r i v a t e S t r i n g cne ;
// C o n s t r u c t e u r
p u b l i c Etudiant ( S t r i n g nom , S t r i n g prenom , S t r i n g cne ) {
super (nom , prenom ) ;
t h i s . prenom = prenom ;
}
...
}
31
c l a s s EtudiantEtranger ex t e n ds Etudiant {
private String nationalite ;
// C o n s t r u c t e u r
p u b l i c EtudiantEtranger ( S t r i n g nom , S t r i n g prenom ,
S t r i n g cne , S t r i n g n a t i o n a l i t e ) {
super (nom , prenom , cne ) ;
this . nationalite = nationalite ;
}
...
}
Listing 4.10 Héritage multiple et constructeurs
4.7.3 Exemple 3
c l a s s Re ct an gl e {
p r i v a t e double l a r g e u r ;
p r i v a t e double hauteur ;
p u b l i c R ec ta ng le ( double l , double h ) {
largeur = l ;
hauteur = h ;
}
...
}
c l a s s Carre e x t en d s R e ct an gl e {
p u b l i c Carre ( double t a i l l e ) {
super ( t a i l l e , t a i l l e ) ;
}
...
}
Listing 4.11 Héritage et constructeurs
Remarques :
1. super doit être la première instruction dans le constructeur et ne doit pas être appelé 2
fois.
2. Il n'est pas nécessaire d'appeler super lorsque la super-classe admet un constructeur par
défaut. Cette tâche sera réalisée par le compilateur.
3. Les arguments de super doivent être ceux d'un des constructeur de la super-classe.
4. Aucune autre méthode ne peut appeler super(...).
5. Il n'y a pas de : super.super.
32
4.8 Opérateur instanceof
Pour les types primitifs, les instructions suivantes sont vraies :
int i ;
float x;
double y ;
...
x = i;
y = x;
i = x;
x = y;
A a = new B ( . . . ) ; //a est de type A , mais l'objet référencé par a est de type B .
A a1 ;
B b = new B ( ) ;
a1 = b ; // a1 de type A , référence un objet de type B
A a=new A ( ) ;
B b;
b=a ; // e r r e u r : on ne peut pas c o n v e r t i r du type << A >> v e r s l e type
B
33
Etudiant e = new Etudiant ( ) ;
EtudiantEtranger eEtr = new EtudiantEtranger ( ) ;
P r o f e s s e u r p r o f = new P r o f e s s e u r ( ) ;
La méthode info() est ajoutée aux diérentes classes pour indiquer dans quelle classe on se
trouve :
void i n f o ( ) {
System . out . p r i n t l n ( " C l a s s e . . . " ) ;
}
On reviendra plus en détails sur l'utilisation des tableaux dans le chapitre concernant les ta-
bleaux.
instanceof
Si B est une sous classe de A alors l'instruction :
b instanceof A ; retourne true.
L'instruction personne instanceof Object; retourne true car toutes les classes héritent,
par défaut, de la classe Object
34
Chapitre 5
Chaînes de caractères
5.1 Introduction
Considérons l'exemple suivant (gure 5.1). Dans cet exemple, on veut comparer les deux chaînes
de caractères nom initialisé avec "smi" et autreNom qui est saisi par l'utilisateur.
import j a v a . u t i l . Scanner ;
p u b l i c c l a s s TestComparaisonChaines {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
S t r i n g nom = " smi " ;
S t r i n g autreNom ;
Scanner i n p ut = new Scanner ( System . i n ) ;
System . out . p r i n t ( " S a i s i r l e nom : " ) ;
autreNom = i np u t . nextLine ( ) ;
i f (nom == autreNom )
System . out . p r i n t l n (nom + " e s t e g a l e a " + autreNom ) ;
else
System . out . p r i n t l n (nom + " e s t d i f f e r e n t de " + autreNom ) ;
}
}
Listing 5.1 Problème de comparaisons de chaînes de caractères
Remarque :
L'utilisation de l'opérateur == implique la comparaison entre les références et non du contenu.
En java, il existe trois classes qui permettent la manipulation des caractères et des chaînes de
35
caractères :
Character : une classe qui permet la manipulation des caractères (un seul caractère).
String : manipule les chaînes de caractères xes.
StringBuilder et StringBuer : manipulent les chaînes de caractères modiables.
Exemple :
public c l a s s TestCaracteres {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
char t e s t= ' a ' ;
i f ( Character . isUpperCase ( t e s t ) )
System . out . p r i n t l n ( t e s t + " e s t majuscule " ) ;
else
System . out . p r i n t l n ( t e s t + " n ' e s t pas majuscule " ) ;
t e s t = Character . toUpperCase ( t e s t ) ;
System . out . p r i n t l n ( " Apres toUpperCase ( ) : " + t e s t ) ;
}
}
Listing 5.2 Utilisation des méthodes de la classe Character
36
5.3 La classe String
5.3.1 Déclaration
Comme on l'a vu dans les chapitres précédents, la déclaration d'une chaîne de caractères se fait
comme suit :
String nom;
L'initialisation se fait comme suit :
nom="Oujdi";
Les deux instructions peuvent être combinées :
String nom = "Oujdi";
L'opérateur new peut être utilisé :
String nom = new String("Oujdi");
Pour créer une chaîne vide : String nom = new String();
5.3.2 Remarques
Une chaîne de type "Oujdi" est considérée par java comme un objet. Les déclarations suivantes :
String nom1 = "Oujdi";
String nom2 = "Oujdi";
déclarent deux variables qui référencent le même objet ("Oujdi").
Par contre, les déclarations suivantes :
String nom1 = new String("Oujdi");
String nom2 = new String("Oujdi"); //ou nom2 = new String(nom1)
déclarent deux variables qui référencent deux objets diérents.
Pour éviter les erreurs de ce type, la classe String contient des méthodes pour manipuler
les chaînes de caractères. Dans la table 5.2, nous donnons quelques unes de ces méthodes.
37
charAt() Retourne un caractère de la chaîne
compareTo() Compare la chaîne avec une autre chaîne
concat() Concaténer une chaîne avec une autre
contains() Vérie si une chaîne contient une autre chaîne
endsWith() Vérie si une chaîne se termine par un suxe
equals() Compare une chaîne avec une autre chaîne
equalsIgnoreCase() Compare une chaîne avec une autre chaîne en ignorant la casse (majuscule
ou minuscule)
getBytes() Copie les caractères d'une chaîne dans un tableau de bytes
getChars() Copie les caractères d'une chaîne dans un tableau de caractères
hashCode() Retourne le code de hachage (hashcode) d'une chaîne
indexOf() Cherche la première occurrence d'un caractère ou d'une sous-chaîne de la
chaîne
isEmpty() Retourne true si la chaîne est de taille nulle
lastIndexOf() Cherche la dernière occurrence d'un caractère ou d'une sous-chaîne dans une
chaîne
length() Retourne la taille de la chaîne
replace() Remplace toutes les occurrences d'un caractère avec un autre caractère
replaceAll() Remplace toutes les occurrences d'une expression régulière par une chaîne
replaceFirst() Remplace la première occurrence d'une expression régulière par une chaîne
split() Sépare la chaîne en un tableau de chaînes en utilisant une expression régulière
comme délimiteur
startsWith() Vérie si une chaîne commence par un suxe
substring() Retourne une sous-chaîne de la chaîne
toCharArray() Met la chaîne dans un tableau de caractères
toLowerCase() Convertie la chaîne en minuscule
toString() Convertie la valeur d'un objet en une chaîne
toUpperCase() Convertie la chaîne en majuscule
trim() supprime les séparateurs de début et de n (espace, tabulation, ...)
valueOf() Retourne la chaîne qui est une représentation d'une valeur
Table 5.2 Quelques méthodes de traitement des chaînes de caractères
38
Une correction de l'exemple précédent est :
p u b l i c c l a s s ProblemeManipStringCorrection {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
f o r ( i n t i =0; i <5; i ++)
System . out . p r i n t l n ( " Oujdi " . charAt ( i ) ) ;
}
}
39
double x =10.2;
s t r = S t r i n g . valueOf ( x ) ; // s t r <−− " 1 0 . 2 "
int test = 20;
s t r = S t r i n g . valueOf ( t e s t ) ; // s t r <−− "20"
}
}
Listing 5.3 Utilisation des méthodes de la classe String
Exemple :
p u b l i c c l a s s TestConversion {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s )
{
double x = 4 5 . 5 ;
S t r i n g s t r = Double . t o S t r i n g ( x ) ; // s t r <−− " 4 5 . 5 "
s t r = "5" ;
t e s t = I n t e g e r . p a r s e I n t ( s t r ) ; // t e s t <−− 5
}
}
Listing 5.4 Conversion entre String et types primitifs
40
achera quelque chose comme : Etudiant@1b7c680.
Cette valeur correspond à la référence de l'objet.
Si on souhaite acher le contenu de l'objet en utilisant le même code, il faut utiliser la méthode
toString.
Par exemple :
p u b l i c c l a s s TestEtudiantToString {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Etudiant etud = new Etudiant ( " Oujdi " , " A l i " , "A20" ) ;
System . out . p r i n t l n ( etud ) ;
}
}
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
...
public String toString (){
r e t u r n "Nom : "+nom+"\nPrenom : "+prenom+"\nCNE : "+cne ;
}
...
}
Achera :
Nom : Oujdi
Prenom : Ali
CNE : A20
achera toujours Differents , du fait que la comparaison s'est faite entre les références des
objets.
Comme pour la méthode toString, Java prévoit l'utilisation de la méthode equals qui pourra
être dénie comme suit :
p u b l i c c l a s s TestEtudiantToString {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Etudiant etud = new Etudiant ( " Oujdi " , " A l i " , "A20" ) ;
41
Etudiant etud1 = new Etudiant ( " Oujdi " , " A l i " , "A20" ) ;
i f ( etud . e q u a l s ( etud1 ) )
System . out . p r i n t l n ( " I d e n t i q u e s " ) ;
else
System . out . p r i n t l n ( " D i f f e r e n t s " ) ;
}
}
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
...
p u b l i c boolean e q u a l s ( Etudiant b i s ){
i f (nom == b i s . nom && prenom == b i s . prenom && cne == b i s . cne )
return true ;
else
return f a l s e ;
}
}
42
Remarque :
L'instruction :
StringBuilder message = "Bonjour";
est incorrecte. Idem, si message est un StringBuilder, alors l'instruction :
message = "Bonjour";
est elle aussi incorrecte.
Remarque :
On ne peut pas faire la concaténation avec l'opérateur + entre des StringBuilder. Par contre
StringBuilder + String produit une nouvelle chaîne de type String.
43
char c = s t r B u i l d e r . charAt ( 2 ) ; // c <−− ' n '
s t r = s t r B u i l d e r + " t o u s l e monde" ;
// s t r <−− " Bonjour t o u s l e monde"
}
}
Listing 5.5 Utilisation des méthodes de la classe StringBuilder
44
Chapitre 6
Tableaux
Remarques :
En java, un tableau :
est un objet ;
est alloué dynamiquement (avec l'opérateur new) ;
a un nombre xe d'éléments de même type ;
peut être vide (taille zéro).
La création d'un tableau peut se faire soit, lors de la déclaration soit par utilisation de l'opéra-
teur new.
Exemples :
1. Création par initialisation au début :
int [] tab={12,10,30*4};
2. Création par utilisation de new :
int [] tab;
tab = new int[5];
ou bien :
int [] tab = new int[5];
45
La déclaration
double[] tab = new double[5];
Crée un emplacement pour un tableau de 5 réels (double) et fait la référence à tab comme
illustré par le schéma suivant :
tab −−−−−−−−→ 0.0 0.0 0.0 0.0 0.0
Les valeurs du tableau sont initialisés aux valeurs par défaut (0 pour int, 0.0 pour double ...).
Exemple :
double[] scores = new double[10];
System.out.println(scores .length); //Ache 10
Remarque :
La taille d'un tableau ne peut pas être changée. Par contre, la référence du tableau peut changer.
Elle peut référencée un tableau de taille diérente.
46
Exemple :
double[] tab1 = new double[10];
double[] tab2 = new double[5];
tab1 = new double[7];//tab1 est maintenant un nouveau tableau de taille 7
tab2 = tab1;//tab1 et tab2 referencent le meme tableau
Exemple
double [ ] c a r r e s = new double [ 1 0 ] ;
f o r ( i n t i =0; i <c a r r e s . l e n g t h ; i ++)
c a r r e s [ i ]= i * i ;
f o r ( i n t i =0; i <c a r r e s . l e n g t h ; i ++)
System . out . p r i n t f ( " c a r r e s [%d ] = %.2 f \n" , i , c a r r e s [ i ] ) ;
Remarque :
La lecture d'un tableau peut se faire de la façon suivante :
f o r ( double c a r r e : c a r r e s )
System . out . p r i n t l n ( c a r r e ) ;
Cette méthode de parcours d'un tableau n'est valable que pour la lecture et ne peut pas être
utilisée pour la modication. Elle a l'avantage d'éviter l'utilisation des indices.
Dans le listing suivant, pour calculer la somme des éléments du tableau, on n'a pas besoin de
connaître les indices.
double somme = 0 . 0 ;
f o r ( double c a r r e : c a r r e s )
somme += c a r r e ;
47
System . out . p r i n t l n ( " t a i l l e de a r g s "+a r g s . l e n g t h ) ;
f o r ( S t r i n g arg : a r g s )
System . out . p r i n t ( arg . toUpperCase ()+ " " ) ;
Si le programme s'appel Test et exécute la commande java Test bonjour tous le monde ,
alors le code précédent achera :
taille de args : 4
BONJOUR TOUS LE MONDE
Exemple
double [ ] c a r r e s = new double [ 1 0 ] ;
double [ ] c a r r e s B i s = new double [ 1 0 ] ;
double [ ] c a r r e s T e s t = new double [ 6 ] ;
// Copie de c a r r e s dans c a r r e s B i s
System . arraycopy ( c a r r e s , 0 , c a r r e s B i s , 0 , 1 0 ) ;
48
System . arraycopy ( c a r r e s , 4 , c a r r e s T e s t , 0 , 6 ) ;
Exemple
import j a v a . u t i l . Arrays ;
...
double [ ] t1 = new double [ 1 0 ] ;
f o r ( i n t i = 0 ; i < t1 . l e n g t h ; i ++)
t[ i ] = i*i ;
i n t [ ] t2 = Arrays . copyOf ( t1 , 1 0 ) ;
1. crée le tableau t2
2. aecte au tableau t2 les 10 premiers éléments du tableau tab.
i n t [ ] t3= Arrays . copyOfRange ( t1 , debut , f i n ) ;
1. crée le tableau t3
2. aecte à t3 les éléments de t1 situés entre les indices : debut et (n-1) :
Exemple
Soient t1 et t2 deux tableaux de primitifs déjà initialisés :
import j a v a . u t i l . Arrays ;
...
boolean b=Arrays . e q u a l s ( tab1 , tab2 ) ;
49
6.7 Utilisation de la classe Arrays
La classe Arrays contient diérentes méthodes pour la manipulation des tableaux. Nous avons
déjà utilisé les méthodes Arrays.copyOf(), Arrays.copyOfRange(), et Arrays.equals().
Dans ce qui suit, nous allons voir quelques méthodes pratiques :
6.7.1 Trie
La méthode void sort(type[] tab), permet de trier le tableau tab par ordre croissant. Le
résultat du trie est retourné dans tab.
La méthode void sort(type[] tab, int indiceDeb, int indiceFin) permet de trier le tableau
tab par ordre croissant à partir de l'indice indiceDeb (inclue) jusqu'au indiceFin (exclue)
Exemple
double [ ] tab = new double [ 1 0 ] ;
Arrays . s o r t ( tab ) ;
Arrays . s o r t ( tab , 2 , 5 ) ;
// T r i e l e s e l e m e n t s tab [ 2 ] , tab [ 3 ] e t tab [ 4 ] par o r d r e c r o i s s a n t
6.7.2 Recherche
La méthode int binarySearch(type [] a, type val), permet de chercher val dans le tableau
tab. Le tableau doit être trié par ordre croissant, sinon, le résultat de retour sera indéterminé.
Le résultat de retour est :
l'indice du tableau qui contient val si le tableau contient val ;
une valeur négative si le si le tableau ne contient pas val.
La méthode int binarySearch(type [] a, int indiceDeb, int indiceFin, type val), permet
de chercher val dans l'intervalle du tableau tab entre l'indice indiceDeb (inclue) et indiceFin
(exclue).
Exemple
double [ ] tab = new double [ 1 0 ] ;
double v a l =5;
50
f o r ( i n t i =0; i <10; i ++)
tab [ i ] = Math . random ( ) * 1 0 ;
tab [ 3 ] = v a l ;
Arrays . s o r t ( tab ) ;
6.7.3 Remplissage
La méthode void ll(type[] tab, type val) aecte val à tous les éléments du tableau.
La méthode void ll(type[] tab, int indiceDeb, int indiceFin, type val) aecte val aux
éléments du tableau compris entre indiceDeb et indiceFin-1.
Exemple
double [ ] tab = new double [ 1 0 ] ;
double v a l =10;
Arrays . f i l l ( tab , v a l ) ;
v a l =7;
// tab [ 2 ] = tab [ 3 ] = tab [ 4 ]= 7
Arrays . f i l l ( tab , 2 , 5 , v a l ) ;
Exemple
i n t [ ] tab = {1 , 2 , 3 , 4 } ;
51
6.8 Passage et retour d'un tableau dans une méthode
Considérons le programme suivant :
import j a v a . u t i l . Arrays ;
p u b l i c c l a s s TabMethodes {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
f i n a l i n t TAILLE = 4 ;
i n t [ ] tab = {1 , 2 , 3 , 4 } ;
int i ;
// Appel de t e s t ( pour t o u s l e s e l e m e n t s du t a b l e a u )
f o r ( i = 0 ; i < TAILLE ; i ++)
t e s t ( tab [ i ] ) ;
p u b l i c s t a t i c void t e s t ( i n t x ) {
System . out . p r i n t ( "Debut : \ t " + x ) ;
x = 10;
System . out . p r i n t l n ( "\ t f i n : \ t " + x ) ;
}
}
D'après le résultat de l'exécution, le contenu du tableau n'a pas changé du fait que x est
locale à la méthode test() et tout changement de cette valeur ne sera pas visible à l'extérieure
et par conséquent le tableau reste inchangé.
52
aux éléments du tableau. Donc, toute modication aectera le tableau.
Exemple
Le programme suivant :
import j a v a . u t i l . Arrays ;
p u b l i c c l a s s TabMethodesArg {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
i n t [ ] tab = { 1 , 2 , 3 , 4 } ;
// Appel de t e s t ( pour t o u s l e s e l e m e n t s du t a b l e a u )
t e s t ( tab ) ;
p u b l i c s t a t i c void t e s t ( i n t [ ] x ) {
System . out . p r i n t l n ( "Debut : \ t " + Arrays . t o S t r i n g ( x ) ) ;
Arrays . f i l l ( x , 1 0 ) ;
System . out . p r i n t l n ( " f i n : \ t " + Arrays . t o S t r i n g ( x ) ) ;
}
}
achera :
Exemple
La méthode :
public s ta tic int [ ] s c o r e I n i t i a l () {
i n t s c o r e [ ] ={2 , 3 , 6 , 7 , 8 } ;
return score ;
53
}
La déclaration :
Etudiant[] etudiants = new Etudiant[30];
Crée l'emplacement pour contenir 30 objets de type Etudiant . Elle ne crée que les références
vers les objets. Pour créer les objets eux mêmes, il faut utiliser, par exemple, l'instruction
suivante :
f o r ( i n t i =0; i <e t u d i a n t s . l e n g t h ; i ++)
e t u d i a n t s [ i ]=new Etudiant ( ) ;
Attention
Pour les tableaux d'objets, les méthodes de la classe Arrays opèrent sur les références et
non sur les valeurs des objets.
import j a v a . u t i l . Arrays ;
p u b l i c c l a s s TableauxObjets {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Etudiant [ ] etud1 = new Etudiant [ 2 ] ;
54
Etudiant [ ] etud2 = new Etudiant [ 2 ] ;
Etudiant [ ] etud3 = new Etudiant [ 2 ] ;
boolean b ;
// I n i t i a l i s a t i o n de etud1
etud1 [ 0 ] = new Etudiant ( " Oujdi " , " A l i " ) ;
etud1 [ 1 ] = new Etudiant ( " Berkani " , " Lina " ) ;
// I n i t i a l i s a t i o n de etud2
etud2 [ 0 ] = new Etudiant ( "Mohammed" , " A l i " ) ;
etud2 [ 1 ] = new Etudiant ( " F i g u i g u i " , " Fatima " ) ;
etud3 = etud1 ;
b = Arrays . e q u a l s ( etud1 , etud3 ) ;
System . out . p r i n t l n ( b ) ; // a f f i c h e t r u e
}
}
55
Exemple
L'instruction :
matrice = new double[4][3];
crée un tableau de 4 lignes et 3 colonnes.
On peut combiner les deux instructions précédentes :
double [][] matrice = new double[4][3];
Remarques
En langage C, un tableau à plusieurs dimensions est en réalité un tableau à une dimen-
sion. Par exemple, la déclaration :
double matrice [4][3];
crée en mémoire un tableau (contiguë) de 12 double.
En Java, un tableau à plusieurs dimensions n'est pas contiguë en mémoire. En Java, un
tableau de plusieurs dimensions est un tableau de tableaux.
On peut dénir un tableau à 2 dimensions dont les colonnes n'ont pas la même dimension.
Exemple 1
double [ ] [ ] tabMulti = new double [ 2 ] [ ] ;
tabMulti [ 0 ] = new double [ 3 ] ; // tabMulti [ 0 ] e s t un t a b l e a u de 3 double
tabMulti [ 1 ] = new double [ 4 ] ; // tabMulti [ 1 ] e s t un t a b l e a u de 4 double
L'exemple précédent crée un tableau à 2 dimensions dont la première ligne est composée de 3
éléments et la deuxième ligne est composée de 4 éléments.
Exemple 2
Dans l'exemple suivant, on va créer un tableau triangulaire qui sera initialisé comme suit :
0
0 0
0 0 0
0 0 0 0
56
final int N = 4;
i n t [ ] [ ] t a b T r i a n g u l a i r e = new i n t [N ] [ ] ;
f o r ( i n t n=0; n<N; n++)
t a b T r i a n g u l a i r e [ n]= new i n t [ n + 1 ] ;
Exemple
double [ ] [ ] m a t r i c e = new double [ 4 ] [ 3 ] ;
double somme=0;
f o r ( double [ ] l i g n e : m a t r i c e )
f o r ( double v a l : l i g n e )
somme += v a l ;
57
double [][] matrice = {new double[4],new double[5]};
Elle peut se faire au début en aectant des valeurs au tableau :
double [][] tabMultiBis = {{1,2},{3,5},{3,7,8,9,10}};
Exemple
double [ ] [ ] tabMulti = {new double [ 4 ] , new double [ 5 ] } ;
double [ ] [ ] t a b M u l t i B i s = { { 1 , 2 } , { 3 , 5 } , { 3 , 7 , 8 , 9 , 1 0 } } ;
System . out . p r i n t l n ( t a b M u l t i B i s . l e n g t h ) ; // A f f i c h e 3
System . out . p r i n t l n ( t a b M u l t i B i s [ 0 ] . l e n g t h ) ; // A f f i c h e 2
System . out . p r i n t l n ( t a b M u l t i B i s [ 1 ] . l e n g t h ) ; // A f f i c h e 2
System . out . p r i n t ( t a b M u l t i B i s [ 2 ] . l e n g t h ) ; // A f f i c h e 5
58
Chapitre 7
Généralités
Exemple :
public c l a s s VarStatiques {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
System . out . p r i n t l n ( Jeu . m e i l l e u r S c o r e ) ; // Affiche 0
Jeu . m e i l l e u r S c o r e ++;
System . out . p r i n t l n ( Jeu . m e i l l e u r S c o r e ) ; // Affiche 1
Jeu j = new Jeu ( ) ;
j . calculScore ();
System . out . p r i n t l n ( Jeu . m e i l l e u r S c o r e ) ; // A f f i c h e 10
// ou b i e n
System . out . p r i n t l n ( j . m e i l l e u r S c o r e ) ; // A f f i c h e 10
j . calculScore ();
System . out . p r i n t l n ( Jeu . m e i l l e u r S c o r e ) ; // A f f i c h e 20
}
}
c l a s s Jeu {
static int meilleurScore = 0;
int score = 0;
void c a l c u l S c o r e ( ) {
s c o r e += 1 0 ;
i f ( meilleurScore < score ) meilleurScore = score ;
}
}
59
7.1.1 Constantes nal et static
Une constante commune à toutes les instances d'une classe peut être déclarée en nal static .
c l a s s A{
f i n a l s t a t i c double PI =3.1415927;
s t a t i c f i n a l double Pi =3.1415927;
}
Exemple :
p u b l i c c l a s s MethodesClasses {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Scanner c l a v i e r = new Scanner ( System . i n ) ;
int n;
System . out . p r i n t ( " S a i s i r 1 e n t i e r : " ) ;
n = c l a v i e r . nextInt ( ) ;
System . out . p r i n t ( " F a c t o r i e l l e : " + n + " e s t :"
+ Calcul . f a c t o r i e l l e (n ) ) ;
}
}
c l a s s Calcul {
p r i v a t e i n t somme ;
s t a t i c int f a c t o r i e l l e ( int n) {
// ne peut pas u t i l i s e r somme
i f ( n <= 0)
60
return 1;
else
return n * f a c t o r i e l l e (n − 1);
}
}
La classe Math fourni les méthodes statiques sin, cos, pow, ...
On a déjà utilisé quelques méthodes statiques avec les classes String, Integer, Double ...
Exemple :
class A {
f i n a l void meth ( ) {
System . out . p r i n t l n ( "Methode f i n a l e . " ) ;
}
}
c l a s s B e x t e nd s A {
void meth ( ) { // Erreur : ne peut e t r e r e d e f i n i e
System . out . p r i n t l n ( " I l l e g a l ! " ) ;
}
}
Exemple :
final class A {
// . . .
}
61
7.5 Fin de vie des objets
Un objet (ou une variable) est en n de vie lorsqu'il n'est plus utilisé. Il est hors porté.
Exemple 1 :
{
i n t x=12; // x e s t a c c e s s i b l e
{
int q ;
q=x+100; // x e t q t o u s l e s deux s o n t a c c e s s i b l e s
}
x=6;
// x e s t a c c e s s i b l e
q=x+2; // Erreur : q e s t h o r s de p o r t e e
}
Exemple 2 :
p u b l i c c l a s s FinVie {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
afficherUnEtudiant ( ) ;
}
s t a t i c void a f f i c h e r U n E t u d i a n t ( ) {
Etudiant e t = new Etudiant ( " Oujdi " , " A l i " , "A20" ) ;
System . out . p r i n t l n ( e t ) ;
}
}
La référence associé à et n'est plus utilisée par contre l'objet référencé par et existe toujours
mais reste inaccessible.
62
7.6 Ramasse miettes (Garbage collector)
Contrairement au langage C où on la fonction free qui permet de libérer la mémoire occupée
par un pointeur, en Java, il n'y a pas de méthode qui permet de libérer la mémoire occupée
par un objet non référencé.
Par contre il existe un processus qui est lancé automatiquement (de façon régulière) de l'exécu-
tion d'un programme Java et récupère la mémoire non utilisé. Ce processus s'appelle le ramasse
miettes (Garbage collector en anglais).
L'utilisateur peut appeler le ramasse miette en appelant la méthode System.gc();.
Exemple :
p u b l i c c l a s s FinVie {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
...
afficherUnEtudiant ( ) ;
System . gc ( ) ;
...
}
s t a t i c void a f f i c h e r U n E t u d i a n t ( ) {
Etudiant e t = new Etudiant ( " Oujdi " , " A l i " , "A20" ) ;
System . out . p r i n t l n ( e t ) ;
}
}
63
Chapitre 8
Polymorphisme et abstraction
8.1 Introduction
Le mot polymorphisme vient du grecque : poly (pour plusieurs) et morph (forme). Il veut
dire qu'une même chose peut avoir diérentes formes. Nous avons déjà vue cette notion avec
la redénition des méthodes dans le chapitre 4 section 4.6. Une même méthode peut avoir
diérentes dénitions suivant la classe ou elle se trouve.
c l a s s Personne {
...
}
c l a s s Etudiant e xt e n ds Personne {
...
}
c l a s s EtudiantEtranger ex t e n ds Etudiant {
private String nationalite ;
...
}
Puisque un étudiant étranger est lui aussi un étudiant, au lieu de dénir 2 tableaux :
Etudiant[] etudiants = new Etudiant[30];
EtudiantEtranger[] etudiantsEtrangers = new EtudiantEtranger[10];
on pourra dénir un seul tableau comme suit :
Etudiant[] etudiants = new Etudiant[40];
Avant d'utiliser la tableau précédent, considérons la déclaration :
Personne personne;
64
Nous avons vu que les instructions suivantes sont toutes valides :
personne = new Personne();
personne = new Etudiant();
personne = new EtudiantEtranger();
De la même façon on peut initialiser le tableau de la façon suivante :
f o r ( i n t i n t i =0; i <10; i ++)
e t u d i a n t s [ i ] = new Etudiant ( ) ;
e t u d i a n t s [ 1 0 ] = new EtudiantEtranger ( ) ;
e t u d i a n t s [ 1 1 ] = new EtudiantEtranger ( ) ;
...
c l a s s B e x t e nd s A{
p u b l i c void message ( ) {
System . out . p r i n t l n ( " Je s u i s dans l a c l a s s e B" ) ;
}
p u b l i c void f ( ) {
System . out . p r i n t l n ( "Methode f ( ) de l a c l a s s e B" ) ;
}
}
La méthode message() a été redénie dans la classe B et la méthode f() a été ajoutée
dans B.
Considérons les instructions :
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
A a = new A ( ) ;
B b = new B ( ) ;
a . message ( ) ;
b . message ( ) ;
b. f ();
a = new B ( ) ;
a . message ( ) ;
}
65
Dans l'exécution on aura le résultat suivant :
Lorsqu'une méthode est redénie (s'est spécialisée), c'est la version la plus spécialisée qui est
appelée. La recherche de la méthode se fait dans la classe réelle de l'objet. La recherche s'est fait
lors de l'exécution et non lors de la compilation. Ce processus s'appelle la liaison dynamique.
Il s'appelle aussi : liaison tardive, dynamic binding, late-binding ou run-time binding.
Remarques :
Dans les instructions précédentes, la dernière instruction a.message(); fait appel à
la méthode message() de la classe B.
Si on ajoute l'instruction :
a. f ();
après les instructions :
a = new B();
a.message();
on aura une erreur de compilation, du fait que la méthode f() n'est pas implémentée
dans la classe de déclaration de l'objet a même si la classe réelle (la classe B) possède
f() .
La visibilité d'une méthode spécialisée peut être augmentée (par exemple de protected
vers public) mais elle ne peut pas être réduite (par exemple de public vers private)
8.4.1 Exemple
p u b l i c c l a s s MethodesInstances {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ){
Etudiant e = new Etudiant ( ) ;
e . message ( ) ;
e = new EtudiantEtranger ( ) ;
e . message ( ) ;
}
}
c l a s s Etudiant {
p u b l i c void message ( ) {
66
System . out . p r i n t l n ( " Je s u i s un e t u d i a n t " ) ;
}
}
c l a s s EtudiantEtranger ex t e n ds Etudiant {
p u b l i c void message ( ) {
System . out . p r i n t l n ( " Je s u i s un e t u d i a n t e t r a n g e r " ) ;
}
}
Je suis un etudiant
Je suis un etudiant etranger
e = new EtudiantEtranger ( ) ;
e . message ( ) ;
}
}
c l a s s Etudiant {
p u b l i c s t a t i c void message ( ) {
System . out . p r i n t l n ( " Je s u i s un e t u d i a n t " ) ;
}
}
c l a s s EtudiantEtranger ex t e n ds Etudiant {
p u b l i c s t a t i c void message ( ) {
System . out . p r i n t l n ( " Je s u i s un e t u d i a n t e t r a n g e r " ) ;
}
}
Je suis un etudiant
Je suis un etudiant
C'est la classe du type qui est utilisée (ici Etudiant) et non du type réel de l'objet (ici Etudian-
tEtranger).
67
8.5 Abstraction
8.5.1 Exemples introductifs
Exemple 1
Reprenons les classes Personne, Etudiant et EtudiantEtranger et ajoutons aux classes
Etudiant et EtudiantEtranger la méthode saluer() :
c l a s s Etudiant e xt e n ds Personne {
...
p u b l i c void s a l u e r ( ) {
System . out . p r i n t l n ( " Assalam alaikoum " ) ;
}
}
c l a s s EtudiantEtranger ex t e n ds Etudiant {
private String nationalite ;
...
p u b l i c void s a l u e r ( ) {
System . out . p r i n t l n ( " Bonjour " ) ;
}
}
Puisque la méthode saluer() est dénie dans les deux classes Etudiant et EtudiantE-
tranger, on souhaite la dénir dans la classe Personne.
Une première solution consiste à la dénir comme suit :
c l a s s Personne {
...
p u b l i c void s a l u e r ( ) {
}
}
Cette solution est mauvaise du fait que toute classe qui héritera de Personne pourra appeler
cette méthode (qui ne fait rien).
Une deuxième solution consiste à rendre la méthode saluer() abstraite dans Personne et
par conséquent, obliger chaque classe qui hérite de Personne à dénir sa propre méthode.
Remarques :
1. Une méthode abstraite :
ne doit contenir que l'entête et doit être implémenté dans les sous classes ;
doit être public (ne peut pas être privée) ;
est déclarée comme suit :
public abstract typeRetour methAbstr(args);
68
2. Une méthode statique ne peut pas être abstraite.
3. Une classe qui contient une méthode abstraite doit être elle aussi abstraite et doit être
déclarée comme suit :
public abstract class nomClasse{ ... }
4. Une classe abstraite ne peut pas être utilisée pour instancier des objets. Une instruction
telle que :
obj=new nomClasse();
est incorrecte (avec nomClasse est une classe abstraite).
5. Une sous-classe d'une classe abstraite doit implémenter toutes les méthodes abstraites
sinon elle doit être déclarée abstraite.
La classe Personne devient comme suit :
a b s t r a c t c l a s s Personne {
p r i v a t e S t r i n g nom , prenom ;
p u b l i c a b s t r a c t void s a l u e r ( ) ;
public String toString (){
r e t u r n "Nom : " + nom + "Prenom : " + prenom ;
}
}
Exemple 2
Considérons les classes Cercle et Rectangle qui sont des sous classes de la classe FigureGeo-
metrique. Les surfaces d'un cercle et d'un rectangle ne sont pas calculées de la même façon.
Une solution consiste à dénir dans la classe FigureGeometrique une méthode abstraite
surface() et obliger les classes Cercle et Rectangle à implémenter cette méthode.
a b s t r a c t c l a s s FigureGeometrique {
p u b l i c a b s t r a c t double s u r f a c e ( ) ;
}
c l a s s C e r c l e e xt e n ds FigureGeometrique {
p r i v a t e double rayon ;
p u b l i c C e r c l e ( double rayon ) {
t h i s . rayon = rayon ;
}
p u b l i c double s u r f a c e ( ) {
r e t u r n Math . PI * rayon * rayon ;
}
}
c l a s s Re ct an gl e ex t e n ds FigureGeometrique {
p u b l i c double l a r g e u r , l o n g u e u r ;
p u b l i c R ec ta ng le ( double l a r g e u r , double l o n g u e u r ) {
69
this . largeur = largeur ;
t h i s . longueur = longueur ;
}
p u b l i c double s u r f a c e ( ) {
return largeur * longueur ;
}
}
public classeA () {
m( ) ;
}
}
c l a s s c l a s s e B e xt e n d s c l a s s e A {
private int b ;
public classeB () {
b = 1 ; // c l a s s e A ( ) e s t invoquee i m p l i c i t e m e n t j u s t e avant
}
p u b l i c void m( ) { // d e f i n i t i o n de m pour l a c l a s s e B
System . out . p r i n t l n ( "b vaut : " + b ) ;
}
}
8.5.3 Remarque
La classe Math n'est pas une classe abstraite même si on ne peut pas créer une instance de
cette classe. Pour dénir une classe non instanciable , il sut de lui ajouter un et un seul
constructeur privé sans arguments.
Extrait de la classe Math :
p u b l i c f i n a l c l a s s Math {
/* *
70
* Don ' t l e t anyone i n s t a n t i a t e t h i s c l a s s .
*/
p r i v a t e Math ( ) {}
...
}
Toute classe abstraite est non instanciable mais l'inverse n'est pas vrai.
71
Chapitre 9
Interfaces et packages
9.1 Introduction
Le langage c++ permet l'héritage multiple, par contre Java ne permet pas l'héritage multiple.
Pour remédier à ceci, Java utilise une alternative qui est la notion d'interfaces.
Dénition : une interface est un ensemble de méthodes abstraites.
9.2 Déclaration
La déclaration d'une interface se fait comme celle d'une classe sauf qu'il faut remplacer le mot
clé class par interface .
Exemple
p u b l i c i n t e r f a c e Forme {
p u b l i c a b s t r a c t void d e s s i n e r ( ) ;
p u b l i c a b s t r a c t void d e p l a c e r ( i n t x , i n t y ) ;
}
i n t e r f a c e Forme {
double p e r i m e t r e ( ) ;
double s u r f a c e ( ) ;
}
72
9.3 Règles
Une interface est similaire à une classe dans les points suivants :
une interface peut contenir plusieurs méthodes ;
une interface peut se trouver dans un chier séparé (.java) ;
peut se trouver dans un paquetage (voir section 9.7).
Il y a des restrictions concernant les interfaces. Une interface :
ne peut pas instancier un objet et par conséquent ne peut pas contenir de constructeurs ;
ne peut pas contenir d'attributs d'instances. Tous les attributs doivent être static et
nal ;
peut hériter de plusieurs interfaces (héritage multiple autorisé pour les interfaces).
Remarque : dans Java 8, une interface peut contenir des méthodes statiques.
Exemple
c l a s s Re ct an gl e implements Forme {
p r i v a t e double l a r g e u r , l o n g u e u r ;
p u b l i c R ec ta ng le ( double l a r g e u r , double l o n g u e u r ) {
this . largeur = largeur ;
t h i s . longueur = longueur ;
}
p u b l i c double p e r i m e t r e ( ) {
return 2 * ( largeur + longueur ) ;
}
p u b l i c double s u r f a c e ( ) {
return largeur * longueur ;
}
}
73
Exemple
a b s t r a c t c l a s s R ec t an gl e implements Forme {
p r i v a t e double l a r g e u r , l o n g u e u r ;
p u b l i c double s u r f a c e ( ) {
return largeur * longueur ;
}
}
Exemple
Considérons les 2 interfaces I1 et I2 :
i n t e r f a c e I1 { i n t e r f a c e I2 {
f i n a l s t a t i c i n t MAX = 2 0 ; void meth3 ( ) ;
void meth1 ( ) ; void meth4 ( ) ;
void meth2 ( ) ; }
}
74
9.4.3 Implémentation et héritage
Une classe B peut hériter de la classe A et implémenter les 2 interfaces I1 et I2, comme suit :
class B extends A implements I1,I2
9.5.2 Tableaux
Ceci peut être étendu pour les tableaux. Considérons la classe Cercle qui implémente elle aussi
l'interface Forme et la classe Carre qui hérite de Rectangle.
c l a s s C e r c l e implements Forme {
p r i v a t e double rayon ;
p u b l i c C e r c l e ( double rayon ) {
t h i s . rayon = rayon ;
}
p u b l i c double p e r i m e t r e ( ) {
r e t u r n 2 * Math . PI * rayon ;
}
p u b l i c double s u r f a c e ( ) {
r e t u r n Math . PI * rayon * rayon ;
}
}
c l a s s Carre e x t en d s R e ct an gl e {
p r i v a t e double l a r g e u r ;
p u b l i c Carre ( double l a r g e u r ){
super ( l a r g e u r , l a r g e u r ) ;
}
}
75
On pourra écrire :
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Forme [ ] tabForme = new Forme [ 3 ] ;
tabForme [ 0 ] = new Re ct an gl e ( 1 0 , 2 0 ) ;
tabForme [ 1 ] = new C e r c l e ( 3 ) ;
tabForme [ 2 ] = new Carre ( 1 0 ) ;
9.5.3 Casting
Ajoutons à la classe Cercle la méthode diametre() :
c l a s s C e r c l e implements Forme {
p r i v a t e double rayon ;
...
p u b l i c double diametre ( ) {
r e t u r n 2 * rayon ;
}
}
Considérons l'instruction :
Forme forme = new Cercle(5);
L'instruction :
double d = forme.diametre();
génère une erreur de compilation. Pour éviter cette erreur, il faut faire un cast comme suit :
double d = ((Cercle) forme).diametre();
9.6 Héritage
Une interface peut hériter d'une ou plusieurs interfaces.
Exemple
i n t e r f a c e I1 {
f i n a l s t a t i c i n t MAX = 2 0 ;
void meth1 ( ) ;
void meth2 ( ) ;
}
76
i n t e r f a c e I2 {
void meth3 ( ) ;
void meth4 ( ) ;
}
i n t e r f a c e I 3 ex t e n ds I1 , I 2 {
void meth5 ( ) ;
}
i n t e r f a c e I3 {
f i n a l s t a t i c i n t MAX = 2 0 ;
void meth1 ( ) ;
void meth2 ( ) ;
void meth3 ( ) ;
void meth4 ( ) ;
void meth5 ( ) ;
}
9.7 Packages
Un package est un ensembles de classes. Il sert à mieux organiser les programmes. Si on n'utilise
pas de packages dans nos programmes, alors on travail automatiquement dans le package par
défaut (default package).
Pour la saisie à partir du clavier, nous nous avons utilisé la Scanner, pour cela nous avons
importé le package java.util.
9.7.2 Exemple
Considérons la hiérarchie suivante :
77
Nous avons la structure suivante :
le répertoire interfaces contient le répertoire formes et les chiers Declaration.java
et TestInterfaces.java ;
le répertoire formes contient les répertoires symetriques et autres, et les chiers
Forme.java et TestPackages.java ;
le répertoire autres contient le chier TriangleCarre.java ;
le répertoire symetriques contient les chiers Carre.java, Cercle.java et Rectangle.java.
Nous avons la classe TriangleCarre se trouve dans le répertoire autres, donc on doit inclure,
au début l'instruction :
package interfaces .formes.autres;
Nous avons aussi la classe TriangleCarre hérite de la classe Rectangle, donc, on doit inclure
l'instruction :
import interfaces .formes.symetriques.Rectangle;
La classe TriangleCarre aura la structure suivante :
package i n t e r f a c e s . formes . a u t r e s ;
import i n t e r f a c e s . formes . s y m e t r i q u e s . R ec t an gl e ;
p u b l i c c l a s s T r i a n g l e C a r r e e xt e n ds R ec ta ng le {
p r i v a t e double c o t e ;
p u b l i c double s u r f a c e ( ) {
78
r e t u r n super . s u r f a c e ( ) / 2 ;
}
}
La classe TestPackages sert pour tester les diérentes classes, donc on doit inclure, au début
les instructions :
package interfaces .formes.autres;
import interfaces .formes.autres.TriangleCarre;
import interfaces .formes.symetriques.Carre;
import interfaces .formes.symetriques.Cercle;
import interfaces .formes.symetriques.Rectangle;
Pour simplier, on peut remplacer les trois dernières instructions par :
import interfaces .formes.symetriques.*;
La structure de la classe TestPackages est comme suit :
package i n t e r f a c e s . formes ;
import i n t e r f a c e s . formes . a u t r e s . T r i a n g l e C a r r e ;
import i n t e r f a c e s . formes . s y m e t r i q u e s . * ;
p u b l i c c l a s s TestPackages {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Forme [ ] tabForme = new Forme [ 4 ] ;
tabForme [ 0 ] = new R ec ta ng l e ( 1 0 , 2 0 ) ;
tabForme [ 1 ] = new C e r c l e ( 3 ) ;
tabForme [ 2 ] = new Carre ( 1 0 ) ;
tabForme [ 3 ] = new T r i a n g l e C a r r e ( 3 , 4 , 5 ) ;
f o r ( i n t i = 0 ; i < 3 ; i ++)
System . out . p r i n t f ( "%.2 f \ t %.2 f \n" , tabForme [ i ] . s u r f a c e ( ) ,
tabForme [ i ] . p e r i m e t r e ( ) ) ;
}
}
p u b l i c c l a s s Carre e x te n d s R e ct an gl e {
p r i v a t e double l a r g e u r ;
79
p u b l i c Carre ( double l a r g e u r ) {
super ( l a r g e u r , l a r g e u r ) ;
}
double g e t L a r g e u r ( ) {
return largeur ;
}
}
c l a s s Cube e x te n d s Carre {
p u b l i c Cube ( double l a r g e u r ) {
super ( l a r g e u r ) ;
}
p u b l i c double volume ( ) {
r e t u r n s u r f a c e ( ) * super . g e t L a r g e u r ( ) ;
}
}
Remarques
1. Les classes Rectangle et Carre sont dans le même package, donc on n'a pas besoin de
faire importations.
2. La classe Cube est invisible dans les autres packages. Dans la classe TestPackages, une
instruction comme :
Cube cube =new Cube();
génère une erreur de compilation, du fait que la classe TestPackages se trouve dans le
package interfaces.formes
80
Chapitre 10
10.1 Introduction
Une exception est une erreur qui se produit durant l'exécution d'un programme. Les pro-
grammes peuvent générer plusieurs types d'exceptions :
division par zéro ;
une mauvaise valeur entré par l'utilisateur (une chaîne de caractères au lieu d'un entier) ;
dépassement des capacités d'un tableau ;
lecture ou écriture dans un chier qui n'existe pas, ou pour lequel le programme n'a pas
les droits d'accès ;
...
Ces erreurs sont appelés exceptions du fait qu'elles sont exceptionnelles.
p u b l i c s t a t i c double f ( double x ) {
r e t u r n Math . s q r t ( x − 1);
}
f(0.0) = NaN
81
p u b l i c s t a t i c double f ( double x ) {
i f ( x >= 1)
r e t u r n Math . s q r t ( x − 1 ) ;
else {
System . out . p r i n t l n ( " Erreur " ) ;
r e t u r n − 1;
}
}
Le problème avec ce code c'est qu'il fait un achage, qui n'est pas prévu par la fonction, de
plus, il retourne une valeur qui n'est pas vraie qui pourrait aboutir à de mauvaises conséquences
pour le reste du programme.
Le code précédent peut être généralisé en utilisant les exceptions.
10.3 Exceptions
Error et Exception.
En java, il y a deux classes pour gérer les erreurs :
Les deux classes sont des sous-classe de la classe Throwable comme le montre la gure sui-
vante :
82
// permet de g e r e r des t a b l e a u x dynamiques ( v e c t e u r s )
import j a v a . u t i l . Vector ;
public c l a s s Erreurs {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
Vector<Double> l i s t e = new Vector<Double > ( ) ;
boolean b = t r u e ;
while (b) {
l i s t e . add ( 2 . 0 ) ;
}
}
}
import j a v a . u t i l . Scanner ;
public c l a s s Exceptions {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
int n;
Scanner c l a v i e r = new Scanner ( System . i n ) ;
System . out . p r i n t ( " S a i s i r un e n t i e r : " ) ;
n=c l a v i e r . n e x t I n t ( ) ;
System . out . p r i n t l n ( " 1/ " + n + " = " + 1/n ) ;
System . out . p r i n t l n ( " Fin du programme" ) ;
clavier . close ();
}
}
83
import j a v a . u t i l . Scanner ;
public c l a s s Exceptions {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
int n;
Scanner c l a v i e r = new Scanner ( System . i n ) ;
System . out . p r i n t ( " S a i s i r un e n t i e r : " ) ;
n=c l a v i e r . n e x t I n t ( ) ;
i f ( n != 0)
System . out . p r i n t l n ( " 1/ " + n + " = " + 1 / n ) ;
else
System . out . p r i n t l n ( " I m p o s s i b l e de d i v i s e r par 0" ) ;
System . out . p r i n t l n ( " Fin du programme" ) ;
clavier . close ();
}
}
Maintenant, si on saisi une chaîne de caractères au lieu d'un entier, le programme précédent
génère l'erreur suivante :
84
Exception Description
NumberFormatException Mauvaise conversion d'une chaîne de caractères vers un
type numérique. Par exemple :
String s = "tt";
x = Double.parseDouble(s);
StringIndexOutOfBoundsException Indice qui dépasse les limites d'une chaîne de caractères.
Par exemple :
String s = "tt";
char c = s.charAt(2); ou bien char c = s.charAt(−1);
NullPointerException Mauvaise utilisation d'une référence. Par exemple utilisa-
tion d'un tableau d'objets créé mais non initialisé :
A [] a = new A[2]; // A une classe
a [0]. x = 2; // l ' attribut x est public
// . . .
finally{
// code a e x e c u t e r avant l a f i n du b l o c t r y
}
// code a p r e s t r y
public c l a s s DiviseZero {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
int n = 0;
System . out . p r i n t l n ( " 1/ " + n + " = " + 1/n ) ;
}
}
public c l a s s DiviseZero {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
int n = 0;
try {
System . out . p r i n t l n ( " 1/ " + n + " = " + 1 / n ) ;
System . out . p r i n t l n ( "Ne s e r a pas a f f i c h e " ) ;
} c a tc h ( A r i t h m e t i c E x c e p t i o n exOb ) {
System . out . p r i n t l n ( " D i v i s i o n par z e r o " ) ;
}
System . out . p r i n t l n ( " Reste du programme" ) ;
}
}
86
import j a v a . u t i l . Scanner ;
public c l a s s Exceptions {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
int n;
Scanner c l a v i e r = new Scanner ( System . i n ) ;
System . out . p r i n t ( " S a i s i r un e n t i e r : " ) ;
n=c l a v i e r . n e x t I n t ( ) ;
System . out . p r i n t l n ( " 1/ " + n + " = " + 1/n ) ;
System . out . p r i n t l n ( " Fin du programme" ) ;
clavier . close ();
}
}
et traitons les diérentes exceptions générées par le programme et améliorons ce dernier pour
forcer l'utilisateur à saisir un entier :
Le programme suivant :
// Pour p o u v o i r u t i l i s e r " InputMismatchException "
import j a v a . u t i l . InputMismatchException ;
import j a v a . u t i l . Scanner ;
public c l a s s Exceptions {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
int n;
Scanner c l a v i e r = new Scanner ( System . i n ) ;
boolean b = t r u e ;
while (b) {
try {
System . out . p r i n t ( " S a i s i r un e n t i e r : " ) ;
n = c l a v i e r . nextInt ( ) ;
System . out . p r i n t l n ( " 1/ " + n + " = " + 1 / n ) ;
break ;
} c a tc h ( A r i t h m e t i c E x c e p t i o n e ) {
System . out . p r i n t l n ( " I m p o s s i b l e de d i v i s e r par 0" ) ;
System . out . p r i n t l n ( e . getMessage ( ) ) ;
} c a tc h ( InputMismatchException e ) {
System . out . p r i n t l n ( "Vous n ' avez pas s a i s i un e n t i e r " ) ;
System . out . p r i n t l n ( e ) ; // e q u i v a l e n t a e . t o S t r i n g ( )
// pour r e c u p e r e r l e r e t o u r a l a l i g n e
c l a v i e r . nextLine ( ) ;
}
}
System . out . p r i n t l n ( " Fin du programme" ) ;
clavier . close ();
}
}
87
Remarque :
Puisque les classe ArithmeticException et InputMismatchException sont des sous classes
de la classe Exception, on peut les combiner dans bloc catch générique qui utilise la classe
Exception :
public c l a s s ExceptionsGeneriques {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
int n;
Scanner c l a v i e r = new Scanner ( System . i n ) ;
try {
System . out . p r i n t ( " S a i s i r un e n t i e r : " ) ;
n = c l a v i e r . nextInt ( ) ;
System . out . p r i n t l n ( " 1/ " + n + " = " + 1 / n ) ;
} c a tc h ( Exception e ) {
System . out . p r i n t l n ( " Erreur \n" + e . t o S t r i n g ( ) ) ;
}
System . out . p r i n t l n ( " Fin du programme" ) ;
clavier . close ();
}
}
Exemple :
public class BlocFinally {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
i n t tab [ ] = new i n t [ 2 ] ;
try {
tab [ 2 ] = 1 ;
} c a tc h ( ArrayIndexOutOfBoundsException e ) {
System . out . p r i n t l n ( " Exception : " ) ;
e . printStackTrace ( ) ;
// ou b i e n e . p r i n t S t a c k T r a c e ( System . out ) ;
} finally {
tab [ 0 ] = 6 ;
System . out . p r i n t l n ( " tab [ 0 ] = " + tab [ 0 ] ) ;
System . out . p r i n t l n ( "Le b l o c f i n a l l y e s t e x e c u t e " ) ;
}
}
}
88
10.7.4 Blocs try imbriqués
On peut mettre un bloc try dans un autre bloc try.
import j a v a . i o . BufferedReader ;
import java . io . BufferedWriter ;
import j a v a . i o . FileNotFoundException ;
import java . io . FileReader ;
import java . io . FileWriter ;
import j a v a . i o . IOException ;
p u b l i c c l a s s MultipleTry {
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
// Permet d ' o u v r i r un f i c h i e r en e c r i t u r e
B u f f e r e d W r i t e r out = new B u f f e r e d W r i t e r (
new F i l e W r i t e r ( " t e s t . t x t " ) ) ;
out . append ( " Simple t e s t \n" ) ;
f o r ( i n t i = 0 ; i < 5 ; i ++)
out . append ( " i = " + i + "\n" ) ;
out . c l o s e ( ) ;
} c a tc h ( IOException e ) {
e . printStackTrace ( ) ;
}
try {
// Permet d ' o u v r i r un f i c h i e r en l e c t u r e
BufferedReader f i c h i e r = new BufferedReader (
new F i l e R e a d e r ( " t e s t . t x t " ) ) ;
String ligne ;
try {
// l e c t u r e du f i c h i e r l i g n e par l i g n e
w h i l e ( ( l i g n e = f i c h i e r . r e a d L i n e ( ) ) != n u l l ) {
System . out . p r i n t l n ( l i g n e ) ;
}
} c a tc h ( IOException e ) {
e . printStackTrace ( ) ;
}
} c a tc h ( FileNotFoundException e1 ) {
e1 . p r i n t S t a c k T r a c e ( ) ;
}
}
}
89
c l a s s Personne {
p r i v a t e S t r i n g nom , prenom ;
p r i v a t e i n t age ;
90
Remarque :
Dans une méthode, une instruction de type :
Personne p = new Personne("Oujdi","Ali",18);
génère une erreur de compilation du fait que le constructeur génère des exceptions, il faut gérer
les exceptions en utilisant le bloc try.
Exemple :
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
Personne p = new Personne ( " Oujdi " , " A l i " , − 12);
System . out . p r i n t l n ( p ) ;
} c a tc h ( AgeException e ) {
System . out . p r i n t l n ( e ) ;
System . e x i t ( − 1);
}
}
f o r ( i n t i = 0 ; i <= 9 ; i ++)
i f (nom . c o n t a i n s ( S t r i n g . valueOf ( i ) )
| | prenom . c o n t a i n s ( S t r i n g . valueOf ( i ) ) ) {
91
b = true ;
break ;
}
i f ( age < 0)
throw new AgeException ( ) ;
e l s e i f (b)
throw new PersonneException ( ) ;
else {
t h i s . nom = nom ;
t h i s . prenom = prenom ;
t h i s . age = age ;
}
}
...
}
Puisque le constructeur doit gérer deux exceptions, on doit les tester tous les deux lors de
l'instanciation d'un nouveau objet :
Exemple :
p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
Personne p = new Personne ( "OUjdi" , " a1Li " , 1 2 ) ;
System . out . p r i n t l n ( p ) ;
} c a tc h ( AgeException e ) {
System . out . p r i n t l n ( e ) ;
System . e x i t ( − 1);
} c a tc h ( PersonneException e ) {
System . out . p r i n t l n ( e ) ;
System . e x i t ( − 1);
}
}
Exemple :
Soit la classe Etudiant dénie comme suit :
c l a s s Etudiant {
p r i v a t e S t r i n g nom , prenom , cne ;
92
p r i v a t e double [ ] note = new double [ 6 ] ;
p u b l i c void s e t N o te ( i n t i , double x ) {
note [ i ] = x ;
}
...
}
Supposons qu'on veut générer une exception si l'utilisateur veut mettre une note diérente de
-1 ou non comprise entre 0 et 20 (par exemple : setNot(3,29) ou setNot(3,−10)).
Pour cette raison, nous allons dénir une nouvelle classe, appelée NoteException qui hérite
de la classe Exception :
c l a s s NoteException e x t e nd s Exception {
p u b l i c NoteException ( ) {
System . out . p r i n t l n ( "Une note d o i t e t r e e g a l e a −1
ou comprise e n t r e 0 e t 20 " ) ;
}
}
Pour une utilisation dans une méthode main() , on appelle la méthode setNote() comme
suit :
try {
e t 1 . s e tN o t e ( 3 , 2 3 ) ;
System . out . p r i n t l n ( e t 1 . getNote ( 3 ) ) ;
} c a tc h ( NoteException e ) {
System . out . p r i n t l n ( e ) ;
}
93