Introduction au langage Java
Introduction au langage Java
2 Syntaxe du langage 7
2.1 Types de données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Types primitifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.2 Tableaux et matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.3 Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Opérateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3 Structures de contrôle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.1 Instructions conditionnelles . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.2 Instructions itératives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.3 Instructions break et continue . . . . . . . . . . . . . . . . . . . . . . . . . 12
4 Héritage 9
4.1 Principe de l’héritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
iii
4.1.1 Redéfinition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.1.2 Polymorphisme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.3 Classes abstraites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.4 Classes et méthodes génériques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
iv
6 Gestion des entrées/sorties simples 33
6.1 Flux d’entrée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
6.1.1 Lecture des entrées clavier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
6.1.2 Lecture à partir d’un fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
6.1.3 Lecture d’objets enregistrés . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
6.2 Flux de sortie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
6.2.1 Ecriture sur la sortie standard “écran” . . . . . . . . . . . . . . . . . . . . . 3
6.2.2 Ecriture dans un fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
6.2.3 Ecriture d’objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
v
Table des
matières
Chapitre 1
Le langage Java est un langage généraliste de programmation synthétisant les principaux lan-
gages existants lors de sa création en 1995 par Sun Microsystems. Il permet une
programmation orientée-objet (à l’instar de SmallTalk et, dans une moindre mesure, C++),
modulaire (langage ADA) et reprend une syntaxe très proche de celle du langage C.
Outre son orientation objet, le langage Java a l’avantage d’être modulaire (on peut écrire des
portions de code génériques, c-à-d utilisables par plusieurs applications), rigoureux (la
plupart des erreurs se produisent à la compilation et non à l’exécution) et portable (un même
programme compilé peut s’exécuter sur différents environnements). En contre-partie, les
applications Java ont le défaut d’être plus lentes à l’exécution que des applications programmées
en C par exemple.
Un programmeur Java écrit son code source, sous la forme de classes, dans des fichiers
dont l’extension est .java. Ce code source est alors compilé par le compilateur javac en un
langage appelé bytecode et enregistre le résultat dans un fichier dont l’extension est .class. Le
vi
bytecode
vi
Chapitre 1. Introduction au langage Java
ainsi obtenu n’est pas directement utilisable. Il doit être interprété par la machine virtuelle de Java
qui transforme alors le code compilé en code machine compréhensible par le système d’exploita-
tion. C’est la raison pour laquelle Java est un langage portable : le bytecode reste le même quelque
soit l’environnement d’exécution.
En 2009, Sun Microsystems est racheté par Oracle Corporation qui fournit dorénavant les
outils de développement Java SE (Standard Edition) contenus dans le Java Development Kit
(JDK). Au moment où est écrit ce livret, la dernière version stable est le JDK 1..
1.1.1 Compilation
La compilation s’effectue par la commande javac suivie d’un ou plusieurs nom de fichiers
contenant le code source de classes Java. Par exemple, javac [Link] compile la classe
My- Prog dont le code source est situé dans le fichier [Link]. La compilation nécessite
souvent la précision de certains paramètres pour s’effectuer correctement, notamment lorsque le
code source fait référence à certaines classes situées dans d’autres répertoires que celui du code
compilé. Il faut alors ajouter l’option -classpath suivie des répertoires (séparés par un ; sous
Windows et : sous Unix) des classes référencées. Par exemple :
javac -classpath /prog/exos1:/cours [Link]
compilera le fichier [Link] si celui-ci fait référence à d’autres classes situées dans les ré-
pertoires /prog/exos1 et /cours. Le résultat de cette compilation est un fichier nommé My-
[Link] contenant le bytecode correspondant au source compilé. Ce fichier est créé par
défaut dans le répertoire où la compilation s’est produite. Il est cependant fortement
souhaitable de ne pas mélanger les fichiers contenant le code source et ceux contenant le
bytecode. Un répertoire de destination où sera créé le fichier [Link] peut être précisé par
javac -d,
l’option -d par
/prog/exos1
exemple : -classpath /cours [Link]
1.1.2 Interprétation
Le bytecode obtenu par compilation ne peut être exécuté qu’à l’aide de l’interpréteur. L’exé-
cution s’effectue par la commande java suivie du nom de la classe à exécuter (sans
l’extension
.class). Comme lors de la compilation, il se peut que des classes d’autres répertoires soient né-
cessaires. Il faut alors utiliser l’option -classpath comme dans l’exemple qui suit :
java -classpath /prog/exos1:/cours MyProg
2
1.2. Programmation orientée-objet
que le program- meur va écrire les traitements, en associant chaque traitement à un objet
donné. Un objet peut
3
Chapitre 1. Introduction au langage Java
être vu comme une entité regroupant un ensemble de données et de méthodes (l’équivalent d’une
fonction en C) de traitement.
1.2.1 Classe
Un objet est une variable (presque) comme les autres. Il faut notamment qu’il soit déclaré
avec son type. Le type d’un objet est un type complexe (par opposition aux types primitifs entier,
caractère, …) qu’on appelle une classe.
Une classe regroupe un ensemble de données (qui peuvent être des variables primitives ou des
objets) et un ensemble de méthodes de traitement de ces données et/ou de données extérieures à
la classe. On parle d’encapsulation pour désigner le regroupement de données dans une classe.
Par exemple, une classe Rectangle utilisée pour instancier des objets représentant des rec-
tangles, encapsule 4 entiers : la longueur et la largeur du rectangle ainsi que la position en abscisse
et en ordonnée de l’origine du rectangle (par exemple, le coin en haut à gauche). On peut
alors imaginer que la classe Rectangle implémente une méthode permettant de déplacer le
rectangle qui nécessite en entrée deux entiers indiquant la distance de déplacement en abscisse et
en ordonnée. L’accès aux positions de l’origine du rectangle se fait directement (i.e. sans passage
de paramètre) lorsque les données sont encapsulées dans la classe où est définie la méthode.
Un exemple, écrit en Java, de la classe Rectangle est donné ci-dessous :
class Rectangle {
int longueur ;
int largeur ;
int origine_x ;
int origine_y ;
int surface() {
return [Link] * [Link] ;
}
}
Encapsulation
Lors de la conception d’un programme orienté-objet, le programmeur doit identifier les objets
et les données appartenant à chaque objet mais aussi des droits d’accès qu’ont les autres objets sur
ces données. L’encapsulation de données dans un objet permet de cacher ou non leur existence
aux autres objets du programme. Une donnée peut être déclarée en accès :
● public : les autres objets peuvent accéder à la valeur de cette donnée ainsi que la modifier ;
4
1.2. Programmation orientée-objet
● privé : les autres objets n’ont pas le droit d’accéder directement à la valeur de cette donnée
(ni de la modifier). En revanche, ils peuvent le faire indirectement par des méthodes de
l’objet concerné (si celles-ci existent en accès public).
Les différents droits d’accès utilisables en Java sont détaillés dans la section 3.2.1.
Méthode constructeur
Chaque classe doit définir une ou plusieurs méthodes particulières appelées des
constructeurs. Un constructeur est une méthode invoquée lors de la création d’un objet. Cette
méthode, qui peut être vide, effectue les opérations nécessaires à l’initialisation d’un objet.
Chaque constructeur doit avoir le même nom que la classe où il est défini et n’a aucune valeur de
retour (c’est l’objet créé qui est renvoyé). Dans l’exemple précédent de la classe rectangle, le
constructeur initialise la valeur des données encapsulées :
class Rectangle {
...
Rectangle(int lon, int lar) {
[Link] = lon ;
[Link] = lar ;
this.origine_x = 0 ;
this.origine_y = 0 ;
}
...
}
Plusieurs constructeurs peuvent être définis s’ils acceptent des paramètres d’entrée différents.
1.2.2 Objet
Instanciation
Un objet est une instance (anglicisme signifiant « cas » ou « exemple ») d’une classe et est
réfé- rencé par une variable ayant un état (ou valeur). Pour créer un objet, il est nécessaire de
déclarer une variable dont le type est la classe à instancier, puis de faire appel à un constructeur de
cette classe. L’exemple ci-dessous illustre la création d’un objet de classe Cercle en Java :
Cercle mon_rond ;
mon_rond = new Cercle();
L’usage de parenthèses à l’initialisation du vecteur, montre qu’une méthode est appelée pour
l’instanciation. Cette méthode est un constructeur de la classe Cercle. Si le constructeur appelé
nécessite des paramètres d’entrée, ceux-ci doivent être précisés entre ces parenthèses (comme lors
d’un appel classique de méthode). L’instanciation d’un objet de la classe Rectangle faisant appel
au constructeur donné en exemple ci-dessous pourra s’écrire :
Rectangle mon_rectangle = new Rectangle(15,5);
5
Chapitre 1. Introduction au langage Java
Pour accéder à une variable associée à un objet, il faut préciser l’objet qui la contient. Le sym-
bole ’.’ sert à séparer l’identificateur de l’objet de l’identificateur de la variable. Une copie de la
longueur d’un rectangle dans un entier temp s’écrit :
int temp = mon_rectangle.longueur ;
La même syntaxe est utilisée pour appeler une méthode d’un objet. Par exemple :
mon_rectangle.deplace(10,-3);
Pour qu’un tel appel soit possible, il faut que trois conditions soient remplies :
1. La variable ou la méthode appelée existe !
2. Une variable désignant l’objet visé existe et soit instanciée.
3. L’objet, au sein duquel est fait cet appel, ait le droit d’accéder à la méthode ou à la
variable (cf. section 3.2.1).
Pour référencer l’objet “courant” (celui dans lequel se situe la ligne de code), le langage Java
fournit le mot-clé this. Celui-ci n’a pas besoin d’être instancié et s’utilise comme une
variable désignant l’objet courant. Le mot-clé this est également utilisé pour faire appel à un
constructeur de l’objet courant. Ces deux utilisations possibles de this sont illustrées dans
l’exemple suivant :
class Carre {
int cote ;
int origine_x ;
int origine_y ;
Carre(int cote) {
this(cote, 0, 0);
}
}
6
Chapitre 2
Syntaxe du
langage
● les commentaires (non traités par le compilateur) se situent entre les symboles “/*” et “*/”
ou commencent par le symbole “//” en se terminant à la fin de la ligne
int a ; // ce commentaire tient sur une ligne
int b ;
ou
/*Ce commentaire nécessite
2 lignes*/
int a ;
1. exception faite des types associés par une relation d’héritage, cf. section 4
8
TABL 2.1 – Type primitifs de données en Java
int a ;
double b = 5.0 ;
a = b ;
int a ;
double b = 5.0 ;
a = (int)b ;
int[] mon_tableau ;
int mon_tableau2[];
Un tableau a toujours une taille fixe ² qui doit être précisée avant l’affectation de valeurs à
ses indices, de la manière suivante :
De plus, la taille de ce tableau est disponible dans une variable length appartenant au tableau
et accessible par mon_tableau.length. On peut également créer des matrices ou des tableaux à
plusieurs dimensions en multipliant les crochets (ex : int[][] ma_matrice;). À l’instar du C,
on accède aux éléments d’un tableau en précisant un indice entre crochets (mon_tableau[3]
est le quatrième entier du tableau) et un tableau de taille n stocke ses éléments à des indices allant
de O à n-1.
2. pour utiliser des ensembles à taille variable, la classe [Link] est très utile
9
2.2. Opérateurs
Chapitre 2. Syntaxe du langage
String s1 = ”hello” ;
String s2 = ”world” ;
String s3 = s1 + ” ” + s2 ;
//Après ces instructions s3 vaut ”hello world”
2.2 Opérateurs
Une liste des opérateurs disponibles en Java est présentée par ordre de priorité
décroissante dans le tableau 2.2.
<condition> doit renvoyer une valeur booléenne. Si celle-ci est vraie c’est <bloc1> (resp.
<instruction1>) qui est exécuté sinon <bloc2> (resp. <instruction2>) est exécuté. La partie
else <bloc2> est facultative.
Exemple :
10
Chapitre 2. Syntaxe du langage
Légende
if (a == b) {
a = 50
; b = 0
;
} else {
a = a - 1 ;
}
10
2.3. Structures de contrôle
3. retour à l’étape 1 ;
4. la boucle est terminée et le programme continue son exécution en interprétant les instruc-
tion suivant le bloc.
Syntaxe :
while (<condition>) <bloc>
Exemple :
while (a != b) a++;
Exemple :
do a++
while (a != b);
Pour...Faire Cette boucle est constituée de trois parties : (i) une initialisation (la déclaration de
variables locales à la boucle est autorisée dans cette partie) ; (ii) une condition d’arrêt ; (iii) un
ensemble d’instructions à exécuter après chaque itération (chacune de ces instructions est séparée
par une virgule). L’exécution de cette instruction suit les étapes suivantes :
1. les initialisations sont effectuées ;
2. la condition (qui doit renvoyer une valeur booléenne) est évaluée. Si celle-ci est vraie
on passe à l’étape 2, sinon on passe à l’étape 6 ;
3. le bloc principal est exécuté ;
4. les instructions à exécuter après chaque itération sont exécutées ;
5. retour à l’étape 2 ;
6. la boucle est terminée et le programme continue son exécution en interprétant les instruc-
tions suivant le bloc principal.
Syntaxe :
for (<init>;<condition>;<instr_post_itération>) <bloc>
Exemple :
3 Question : que se passe-t-il si le break situé après le case ’c’ est omis ?
11
Chapitre 2. Syntaxe du langage
Exemple :
12
Chapitre 3
Éléments de programmation
Java
C:\>java HelloWorld
Hello world
C:\>
4 Remarque : le tableau de chaînes de caractères args qui est un paramètre d’entrée de la mé-
thode main contient des valeurs précisées à l’exécution. Si la classe avait été exécutée par la
ligne de commande “java HelloWorld 4 toto _”, ce tableau contiendrait 3 éléments dont les
valeurs seraient respectivement “4”, “toto” et “_”.
Dans ce premier programme très simple, une seule classe est utilisée. Cependant, la
conception d’un programme orienté-objet nécessite, pour des problèmes plus complexes, de
créer plusieurs classes et la classe exécutable ne sert souvent qu’à instancier les premiers
13
Chapitre 2. Syntaxe du langage
objets. La classe exé- cutable suivante crée un objet en instanciant la classe Rectangle (cf.
section 1.2.1) et affiche sa surface :
14
Chapitre 3. Éléments de programmation
Java
3.1.2 Packages
Un grand nombre de classes, fournies par Java SE, implémentent des données et traitements
génériques utilisables par un grand nombre d’applications. Ces classes forment l’API (Application
Programmer Interface) du langage Java. Une documentation en ligne pour l’API java est
disponible à l’URL :
[Link]
Toutes ces classes sont organisées en packages (ou bibliothèques) dédiés à un thème précis.
Parmi les packages les plus utilisés, on peut citer les suivants :
Package Description
[Link] Classes graphiques et de gestion d’interfaces
[Link] Gestion des entrées/sorties
[Link] Classes de base (importé par défaut)
[Link] Classes utilitaires
[Link] Autres classes graphiques
Pour accéder à une classe d’un package donné, il faut préalablement importer cette classe ou
son package. Par exemple, la classe Date appartenant au package [Link] qui implémente un
ensemble de méthodes de traitement sur une date peut être importée de deux manières :
● une seule classe du package est importée :
import [Link] ;
toutes les classes du package sont importées (même les classes non utilisées) :
import [Link].* ;
import [Link] ;
14
3.2. Variables et méthodes
Il est possible de créer vos propres packages en précisant, avant la déclaration d’une classe, le
package auquel elle appartient. Pour assigner la classe précédente à un package, nommé [Link],
il faut modifier le fichier de cette classe comme suit :
package [Link] ;
import [Link] ;
Enfin, il faut que le chemin d’accès du fichier [Link] corresponde au nom de son
package. Celui-ci doit donc être situé dans un répertoire fr/emse/[Link] accessible à
partir des chemins d’accès définis lors de la compilation ou de l’exécution (voir section 1.1.1).
Élément Autorisations
Variable Lecture et écriture
Méthode Appel de la méthode
Classe Instanciation d’objets de cette classe et
accès aux variables et méthodes de classe
Le mode public n’est, bien sûr, pas le seul type d’accès disponible en Java. Deux autres mot-
clés peuvent être utilisés en plus du type d’accès par défaut : protected et private. Le tableau
3.2 récapitule ces différents types d’accès (la notion de sous-classe est expliquée dans la section
4).
15
Chapitre 3. Éléments de programmation
Java
Si aucun mot-clé ne précise le type d’accès, celui par défaut est appliqué. En général, il est
souhaitable que les types d’accès soient limités et le type d’accès public, qui est utilisé systémati-
quement par les programmeurs débutants, ne doit être utilisé que s’il est indispensable. Cette res-
triction permet d’éviter des erreurs lors d’accès à des méthodes ou de modifications de variables
sans connaître totalement leur rôle.
La classe Math fournit un ensemble d’outils (variables et méthodes) très utiles pour des pro-
grammes devant effectuer des opération mathématiques complexes. Dans la portion de classe re-
produite ci-dessus, on peut notamment y trouver une approximation de la valeur de π et une
mé- thode convertissant la mesure d’un angle d’une valeur en degrés en une valeur en
radians. Dans le cas de cette classe, il est tout a fait inutile de créer et d’instancier un objet à
partir de la classe Math. En effet, la valeur de π ou la conversion de degrés en radians ne vont
pas varier suivant l’objet auquel elles sont rattachées. Ce sont des variables et des méthodes
de classe qui peuvent être invoquées à partir de toute autre classe (car elles sont déclarées en
accès public) de la manière suivante :
3 Question : Dans les sections précédentes, nous avons déjà utilisé une variable de classe et une
méthode de classe. Pouvez-vous trouver lesquelles ?
16
3.2. Variables et méthodes
C Réponse :
la méthode main des classes exécutables est une méthode de classe car elle est appelée
directement à partir d’une classe ;
lorsdel’affichaged’unechaînedecaractèresàl’écranparl’instruction
[Link](…), on fait appel à la variable out de la classe [Link] qui est un
17
Chapitre
Héritage
Dans certaines applications, les classes utilisées ont en commun certaines variables, méthodes
de traitement ou même des signatures de méthode. Avec un langage de programmation orienté-
objet, on peut définir une classe à différent niveaux d’abstraction permettant ainsi de
factoriser certains attributs communs à plusieurs classes. Une classe générale définit alors un
ensemble d’at- tributs qui sont partagés par d’autres classes, dont on dira qu’elles héritent de cette
classe générale. Par exemple, les classes Carre et Rectangle peuvent partager une méthode
surface() ren- voyant le résultat du calcul de la surface de la figure. Plutôt que d’écrire deux
fois cette méthode, on peut définir une relation d’héritage entre les classes Carre et Rectangle.
Dans ce cas, seule la classe Rectangle contient le code de la méthode surface() mais celle-ci
est également utilisable
sur les objets de la classe Carre si elle hérite de Rectangle.
Forme
Rectangle Cercle
Carre
19
Chapitre 3. Éléments de programmation
Java
Pour le moment, nous considérerons la classe Forme comme vide (c’est-à-dire sans aucune va-
riable ni méthode) et nous nous intéressons plus particulièrement aux classes Rectangle et Carre.
20
La classe Rectangle héritant d’une classe vide, elle ne peut profiter d’aucun de ses attributs et
doit définir toutes ses variables et méthodes. Une relation d’héritage se définit en Java par le mot-
clé extends utilisé comme dans l’exemple suivant :
En revanche, la classe Carre peut bénéficier de la classe Rectangle et ne nécessite pas la ré-
écriture de ces méthodes si celles-ci conviennent à la sous-classe. Toutes les méthodes et variables
de la classe Rectangle ne sont néanmoins pas accessibles dans la classe Carre. Pour qu’un
attribut puisse être utilisé dans une sous-classe, il faut que son type d’accès soit public ou
protected, ou, si les deux classes sont situées dans le même package, qu’il utilise le type d’accès
par défaut. Dans cet exemple, les variables longueur et largeur ne sont pas accessibles dans la
class Carre qui doit passer par les méthodes getLargeur() et getLongueur(), déclarées
comme publiques.
4.1.1 Redéfinition
L’héritage intégral des attributs de la classe Rectangle pose deux problèmes :
1. il faut que chaque carré ait une longueur et une largeur égales ;
2. la méthode affiche écrit le mot “rectangle” en début de chaîne. Il serait souhaitable
que ce soit “carré” qui s’affiche.
De plus, les constructeurs ne sont pas hérités par une sous-classe. Il faut donc écrire un construc-
teur spécifique pour Carre. Ceci nous permettra de résoudre le premier problème en écrivant un
constructeur qui ne prend qu’un paramètre qui sera affecté à la longueur et à la largeur. Pour at-
tribuer une valeur à ces variables (qui sont privées), le constructeur de Carre doit faire appel au
21
4.1. Principe
Chapitre 4. de l’héritage
Héritage
constructeur de Rectangle en utilisant le mot-clé super qui fait appel au constructeur de la classe
supérieure comme suit :
4 Remarques :
L’appel au constructeur d’une classe supérieure doit toujours se situer dans un construc-
teur et toujours en tant que première instruction ;
Si aucun appel à un constructeur d’une classe supérieure n’est fait, le constructeur
fait appel implicitement à un constructeur vide de la classe supérieure (comme si la ligne super() étai
Le second problème peut être résolu par une redéfinition de méthode. On dit qu’une méthode
d’une sous-classe redéfinit une méthode de sa classe supérieure, si elles ont la même signature
mais que le traitement effectué est ré-écrit dans la sous-classe. Voici le code de la classe Carre
où sont résolus les deux problèmes soulevés :
Lors de la redéfinition d’une méthode, il est encore possible d’accéder à la méthode redéfinie
dans la classe supérieure. Cet accès utilise également le mot-clé super comme préfixe à la
méthode. Dans notre cas, il faudrait écrire [Link]() pour effectuer le traitement de la
méthode affiche() de Rectangle.
Enfin, il est possible d’interdire la redéfinition d’une méthode ou d’une variable en
introdui- sant le mot-clé final au début d’une signature de méthode ou d’une déclaration de
variable. Il est aussi possible d’interdire l’héritage d’une classe en utilisant final au début de la
déclaration d’une classe (avant le mot-clé class).
4.1.2 Polymorphisme
Le polymorphisme est la faculté attribuée à un objet d’être une instance de plusieurs classes.
Il a une seule classe “réelle” qui est celle dont le constructeur a été appelé en premier (c’est-à-dire
la classe figurant après le new) mais il peut aussi être déclaré avec une classe supérieure à sa classe
réelle. Cette propriété est très utile pour la création d’ensembles regroupant des objets de classes
différentes comme dans l’exemple suivant :
22
Chapitre 4. Héritage
L’opérateur instanceof peut être utilisé pour tester l’appartenance à une classe comme suit :
L’ensemble des classes Java, y compris celles écrites en dehors de l’API, forme une hiérarchie
avec une racine unique. Cette racine est la classe Object dont hérite toute autre classe. En e ffet,
si vous ne précisez pas explicitement une relation d’héritage lors de l’écriture d’une classe, celle-
ci hérite par défaut de la classe Object. Grâce à cette propriété, des classes génériques ¹ de
création et de gestion d’un ensemble, plus élaborées que les tableaux, regroupent des objets
appartenant à la classe Object (donc de n’importe quelle classe).
Une des propriétés induites par le polymorphisme est que l’interpréteur Java est capable
de trouver le traitement à effectuer lors de l’appel d’une méthode sur un objet. Ainsi, pour
plusieurs objets déclarés sous la même classe (mais n’ayant pas la même classe réelle), le
traitement associé à une méthode donné peut être différent. Si cette méthode est redéfinie par la
classe réelle d’un objet (ou par une classe située entre la classe réelle et la classe de déclaration),
le traitement effectué est celui défini dans la classe la plus spécifique de l’objet et qui redéfinie
la méthode.
Dans notre exemple, la méthode affiche() est redéfinie dans toutes les sous-classes de Forme
et les traitements effectués sont :
22
4.2. Interfaces
Résultat :
rectangle 10x20
cercle 15
rectangle 5x30
carré 10
Dans l’état actuel de nos classes, ce code ne pourra cependant pas être compilé. En e ffet, la
fonction affiche() est appelée sur des objets dont la classe déclarée est Forme mais celle-ci ne
contient aucune fonction appelée affiche() (elle est seulement définie dans ses sous-classes).
Pour compiler ce programme, il faut transformer la classe Forme en une interface ou une classe
abstraite tel que cela est fait dans les sections suivantes.
4.2 Interfaces
Une interface est un type, au même titre qu’une classe, mais abstrait et qui donc ne peut
être instancié (par appel à new plus constructeur). Une interface décrit un ensemble de signatures
de méthodes, sans implémentation, qui doivent être implémentées dans toutes les classes qui
im- plémentent l’interface. L’utilité du concept d’interface réside dans le regroupement de
plusieurs classes, tel que chacune implémente un ensemble commun de méthodes, sous un même
type. Une interface possède les caractéristiques suivantes :
elle contient des signatures de méthodes ;
● elle ne peut pas contenir de variables ;
une interface peut hériter d’une autre interface (avec le mot-clé extends) ;
● une classe (abstraite ou non) peut implémenter plusieurs interfaces. La liste des interfaces
implémentées doit alors figurer après le mot-clé implements placé dans la déclaration de
classe, en séparant chaque interface par une virgule.
Dans notre exemple, Forme peut être une interface décrivant les méthodes qui doivent être
implémentées par les classes Rectangle et Cercle, ainsi que par la classe Carre (même si celle-
ci peut profiter de son héritage de Rectangle). L’interface Forme s’écrit alors de la manière
suivante :
Pour obliger les classes Rectangle, Cercle et Carre à implémenter les méthodes
surface() et affiche(), il faut modifier l’héritage de ce qui était la classe Forme en une
implémentation de l’interface définie ci-dessus :
et
23
Chapitre 4. Héritage
Cette structure de classes nous permet désormais de pouvoir compiler l’exemple donné dans la
section 4.1.2 traitant du polymorphisme. En déclarant un tableau constitué d’objets implémentant
l’interface Forme, on peut appeler la méthode affiche() qui existe et est implémentée par
chaque objet.
Si une classe implémente une interface mais que le programmeur n’a pas écrit l’implémenta-
tion de toutes les méthodes de l’interface, une erreur de compilation se produira sauf si la classe
est une classe abstraite.
public Forme() {
this.origine_x = 0 ;
this.origine_y = 0 ;
}
24
4.4. Classes et méthodes génériques
De plus, il faut rétablir l’héritage des classes Rectangle et Cercle vers Forme :
et
package [Link] ;
Nous pouvons remarquer que le type passé en paramètre est noté entre chevrons (ex : <E>), et
qu’il peut ensuite être réutilisé dans le corps de la classe, par des méthodes (ex : la méthode
set renvoie un élément de classe E).
Il est possible de définir des contraintes sur le type passé en paramètre, comme par
exemple une contrainte de type extends ² :
2. Ici, on utilise T extends E pour signaler que le type T est un sous type de E, que E soit une classe ou
une interface (on n’utilise pas implements).
25
Chapitre 4. Héritage
Ceci signifie que la classe SortedList (liste ordonnée que nous voulons définir) est paramé-
trée par le type T qui doit être un type dérivé (par héritage ou interfaçage) de
Comparable<T>. En bref, nous définissons une liste ordonnée d’éléments comparables entre
eux (pour pouvoir les trier), grâce à la méthode int compareTo(T o) de l’interface
Comparable ³ qui permet de comparer un Comparable à un élément de type T.
26
Chapitre 5
Gestion des
exceptions
Lors de l’écriture d’un programme, la prise en compte d’erreurs prend une place très
impor- tante si l’on souhaite écrire un programme robuste. Par exemple, la simple ouverture d’un
fichier peut provoquer beaucoup d’erreurs telles que l’inexistence du fichier, un mauvais format,
une in- terdiction d’accès, une erreur de connexion au périphérique, … Pour que notre
programme soit robuste, il faut que toutes les erreurs possibles soient détectées et traitées.
Certains langages de programmation, dont le langage Java, proposent un mécanisme de prise
en compte des erreurs, fondé sur la notion d’exception. Une exception est un objet qui peut
être émis par une méthode si un événement d’ordre “exceptionnel” (les erreurs rentrent dans
cette catégorie) se produit. La méthode en question ne renvoie alors pas de valeur de retour, mais
émet une exception expliquant la cause de cette émission. La propagation d’une émission se
déroule selon les étapes suivantes :
1. Une exception est générée à l’intérieur d’une méthode ;
2. Si la méthode prévoit un traitement de cette exception, on va au point 4, sinon au point 3 ;
3. L’exception est renvoyée à la méthode ayant appelé la méthode courante, on retourne au
point 2 ;
4. L’exception est traitée et le programme reprend son cours après le traitement de l’excep-
tion.
La gestion d’erreurs par propagation d’exception présente deux atouts majeurs :
● Une facilité de programmation et de lisibilité : il est possible de regrouper la gestion
d’erreurs à un même niveau. Cela évite des redondances dans l’écriture de traitements
d’erreurs et encombre peu le reste du code avec ces traitements.
● Une gestion des erreurs propre et explicite : certains langages de programmation
utilisent la valeur de retour des méthodes pour signaler une erreur à la méthode
appelante. Etant donné que ce n’est pas le rôle de la valeur de retour de décrire une
erreur, il est souvent impossible de connaître les causes réelles de l’erreur. La dissociation
de la valeur de retour et de l’exception permet à cette dernière de décrire précisément la
ligne de code ayant provoqué l’erreur et la nature de cette erreur.
5.1 Déclaration
Il est nécessaire de déclarer, pour chaque méthode, les classes d’exception qu’elle est suscep-
tible d’émettre. Cette déclaration se fait à la fin de la signature d’une méthode par le mot-clé
throws à la suite duquel les classes d’exceptions (séparées par une virgule s’il en existe
27
Chapitre 4. Héritage
plusieurs) qui peuvent être générées sont précisées. La méthode parseInt de la classe Integer est
un bon exemple :
28
Chapitre 5. Gestion des
exceptions
Cette méthode convertit une chaîne de caractères, qui doit contenir uniquement des
chiffres, en un entier. Une erreur peut se produire si cette chaîne de caractères ne contient pas que
des chiffres. Dans ce cas une exception de la classe NumberFormatException est émise.
Une exception peut être émise dans une méthode de deux manières : (i) par une autre mé-
thode appelée dans le corps de la première méthode ; (ii) par la création d’un objet instanciant la
classe Exception (ou la classe Throwable) et la levée explicite de l’exception en utilisant le
mot-clé throw.
L’exemple ci-dessous illustre ce second cas :
28
5.2. Interception et traitement
Dans chacun de ces cas, le traitement consiste à afficher le message d’erreur associé à l’exception.
Classe Description
AWTException Les exceptions de cette classe peuvent se
produire lors d’opérations de type
graphique.
ClassCastException Signale une erreur lors de la conversion
d’un objet en une classe incompatible
avec sa vraie classe.
FileNotFoundException Signale une tentative d’ouverture d’un
fichier inexistant.
IndexOutOfBoundsException Se produit lorsque l’on essaie d’accéder
à un élément inexistant dans
un ensemble.
IOException Les exceptions de cette classe peuvent se
produire lors d’opérations d’entrées/
sorties.
NullPointerException Se produit lorsqu’un pointeur null
est reçu par une méthode n’acceptant
pas cette valeur, ou lorsque l’on
appelle une méthode ou une variable
à partir d’un pointeur null.
Si aucune des classes d’exception ne correspond à un type d’erreur que vous souhaitez ex-
primer, vous pouvez également écrire vos propres classes d’exception. Pour cela, il su ffit de faire
hériter votre classe de la classe [Link].
30
5.4. Classification des erreurs en Java
Erreurs de compilation. Avant même de pouvoir exécuter le programme, notre code source gé-
nère des erreur par le compilateur. Il faut alors réviser et corriger le code pour ne plus
avoir d’erreurs.
Erreurs d’exécution. Alors que notre programme est en cours d’exécution, la JVM étant mal
configurée ou corrompue, le programme s’arrête ou se gèle. A priori, c’est une erreur non
pas due à notre programme, mais à la configuration ou l’état de l’environnement d’exécu-
tion de notre programme.
Exception non vérifiée. Alors que notre programme est en cours d’exécution, une trace de la pile
des exceptions est affichée, pointant vers une partie de notre code sans gestion
d’exception. Visiblement, nous avons utilisé du code qui est capable de lever un exception
non vérifiée (comme NullPointerException). Il faut modifier le programme pour que
cette situation ne survienne pas.
Exception vérifiée. Alors que notre programme est en cours d’exécution, une trace de la pile des
exceptions est affichée, pointant vers une partie de notre code avec gestion d’exception.
Visiblement, nous avons produit du code qui est capable de lever un exception vérifiée
(comme FileNotFoundException) mais les données passées à notre programme ne va-
lide pas ces exceptions (par exemple, lorsque l’on essaie d’ouvrir un fichier qui n’existe
pas). Il faut alors revoir les données passées en paramètre du programme. Notre code a
bien détecté les problèmes qu’il fallait détecter. Le chapitre suivant sur les entrées/sorties
présentent de nombreux exemples relatifs à ce cas.
31
Chapitre 5. Gestion des
exceptions
Chapitre 6
Le package [Link] propose un ensemble de classes permettant de gérer la plupart des en-
trées/sorties d’un programme. Cette gestion consiste à créer un objet flux dans lequel
transitent les données à envoyer ou à recevoir. Un flux connecte un objet Java à un autre élément.
Deux cas sont illustrés dans ce chapitre : les interactions avec un utilisateur (entrée clavier et
sortie écran) et les accès en lecture ou écriture à un fichier.
32
Chapitre 6. Gestion des entrées/sorties simples
Les données provenant de l’utilisation du clavier sont transmises dans un flux d’entrée créé
automatiquement pour toute application Java. On accède à ce flux par la variable statique de la
classe [Link] qui s’appelle in. Ce flux est alors utilisé comme paramètre d’entrée
du constructeur d’un autre flux d’entrée. Pour cet autre flux, on utilise généralement une sous-
classe de Reader pour récupérer les entrées de l’utilisateur sous la forme d’une chaîne de
caractères. La classe Clavier en donne un exemple :
import [Link].* ;
34
6.1. Flux d’entrée
import [Link].* ;
Il arrive souvent d’enregistrer des données dans des fichiers textes. Il peut alors être utile
d’uti- liser un BufferedReader ou un Scanner pour effectuer la lecture. Dans les exemples
suivants, on considère une×matrice 10 10 enregistrée dans un fichier texte [Link] ligne par
ligne, avec les colonnes séparées par des espaces :
import [Link].* ;
35
Chapitre 6. Gestion des entrées/sorties simples
import [Link].* ;
import [Link] ;
import [Link].* ;
import [Link] ;
L’objet qui est lu dans le fichier doit être une instance de la classe [Link].
36
6.2. Flux de sortie
Un flux de sortie est une instance d’une sous-classe de OutputStream. Comme pour les flux
d’entrée, chaque classe de flux de sortie a son propre mode d’écriture de données. Les classes les
plus couramment utilisées sont :
ByteArrayOutputStream permet d’écrire des octets vers le flux de sortie ;
● DataOutputStream permet d’écrire des types de données primitifs de Java vers le flux de
sortie.
● FileOutputStream est utilisé pour écrire dans un fichier. Les objets de cette classe sont
souvent encapsulés dans un autre objet de classe OutputStream qui définit le format des
données à écrire.
● ObjectOutputStream permet d’écrire des objets (c-à-d des instances de classes Java) vers
le flux de sortie, si ces objets implémentent les interfaces Serializable ou
● Externalizable. Writer n’est pas une sous-classe de OutputStream mais représente un
flux de sortie pour chaînes de caractères. Plusieurs sous-classes de Writer permettent la
création de flux pour chaînes de caractères.
L’écriture de données vers un flux de sortie suit le même déroulement que la lecture d’un flux
d’entrée :
1. Ouverture du flux : Elle se produit lors de la création d’un objet de la classe OutputStream.
2. Ecriture de données : Des données sont écrites vers le flux au moyen de la méthode
write() ou d’une méthode équivalente. La méthode précise à employer dépend du
type de flux ouvert.
3. Fermeture du flux : Quand le flux n’est plus nécessaire, il doit être fermé par la méthode
close().
Comme pour les entrées du clavier, l’écriture vers l’écran fait appel à la variable statique out
de la classe System. On appelle généralement la méthode [Link] ou
[Link] comme cela a été fait dans de nombreux exemples de ce livret.
L’écriture dans un fichier se fait par un flux de la classe FileOutputStream qui prend en
entrée un fichier (instance de la classe File). Ce flux de sortie permet d’écrire des caractères dans
le fichier grâce à la méthode write(). L’exemple suivant présente une méthode pour écrire un
texte dans un fichier :
37
Chapitre 6. Gestion des entrées/sorties simples
import [Link].* ;
On peut également utiliser un Writer comme un FileWriter pour écrire des chaînes de
caractères dans un fichier assez simplement. Dans l’exemple suivant, on écrit une série de 10
lignes de 10 entiers aléatoires séparés par des espaces dans un fichier pouvant être lu par la classe
LectureMatrice :
import [Link].* ;
import [Link] ;
38
6.2. Flux de sortie
import [Link].* ;
import [Link] ;
39
Annexe A
Annexe
Lors des premières versions du langage Java, le seul package fourni par défaut par Java SE
permettant de construire des interfaces graphiques était le package [Link]. Depuis la version
1.1 du JDK, il est très fortement recommandé d’utiliser les classes du package [Link] pour
écrire des interfaces graphiques. En effet, le package swing apporte deux avantages conceptuels
par rapport au package awt :
● Les composants swing sont dits “légers” (lightweight) contrairement aux composants “lourds”
(heavyweight) d’awt. L’apparence graphique d’un composant dit lourd dépend du système
d’exploitation car elle fait appel à un composant correspondant dans le système d’exploita-
tion. Avec un composant léger, son apparence (look-and-feel) est fixée et peut être modifiée
dans le code Java et il est donc possible de donner à une fenêtre une apparence à la Win-
dows tout en utilisant Linux.
● Il applique complètement le schéma Modèle-Vue-Contrôleur (cf. section A.1).
La plupart des classes de composants du package swing héritent de classes du package awt en
redéfinissant certaines méthodes pour assurer les deux avantages précédemment cités. Cependant,
le package awt n’est pas entièrement obsolète et certaines de ces classes sont encore utilisées pour
la gestion d’événements (cf. section A.3) ou la disposition des composants (classes implémentant
l’interface LayoutManager).
44
A.2. Composants graphiques
des données ou de l’apparence. Dans ces cas-là, un modèle par défaut est utilisé.
A.2.1 Composants
Nous ne présentons pas ici toutes les classes de composants du package swing pour nous in-
téresser plutôt à la vue et au modèle de chaque composant. L’utilisation de certains composants
est illustrée dans la section A.2.3.
Vue
Modèle
Il existe pour chaque classe de composant, une seconde classe qui gère le modèle de ce com-
posant (par exemple, ButtonModel représente un modèle de bouton). En général un modèle par
défaut est créé dans le constructeur du composant. L’accès à ce modèle est très souvent masqué
car il existe des méthodes, telles que setText() pour changer le texte d’un bouton ou
setSelected() pour changer l’état d’une case à cocher, de la classe de composant qui peuvent
être directement appelées pour changer les données du modèle. Cependant, pour des
45
Annexe A. Applications graphiques (package swing)
composants plus complexes
46
A.2. Composants graphiques
tels que des tables (JTable) ou des arborescences (JTree), il est parfois indispensable de créer un
modèle personnalisé.
A.2.2 Containers
En premier lieu, il convient de rappeler qu’un container est un composant, et, par conséquent,
que tout ce qui a été présenté précédemment est aussi vrai pour les containers. En plus des carac-
téristiques d’un composant simple, un container contient un ensemble de composants ainsi
que des contraintes sur leur disposition. L’ajout d’un composant à un container se fait par une
mé- thode add(). Il existe plusieurs méthodes add() acceptant des paramètres d’entrée
différents. La méthode à utiliser dépend du type de disposition choisi.
L’objet qui gère la disposition des composants est une instance d’une classe qui doit implé-
menter l’interface [Link]. Cet objet doit être ajouté au container, soit lors de
l’appel à son constructeur, soit par la méthode setLayout(). Un seul LayoutManager est auto-
risé par container. Quelques classes utilisées pour la disposition des composants sont présentées
ci-dessous.
BorderLayout. Le container est découpé en cinq cases : une case par côté (gauche, droite, haut
et bas) et une au centre. L’ajout d’un composant se fait en précisant la case à utiliser grâce à des
variables de classe de BorderLayout :
[Link](MyComponent,[Link]);
[Link](MyComponent2,[Link]);
La taille de chaque case dépend : (i) de la largeur maximale entre la case du nord, du sud et
l’addition des largeurs des cases du centre, de l’est et de l’ouest ; (ii) de la hauteur maximale entre
la case à l’est, à l’ouest et l’addition des hauteurs des cases du centre, du nord et du sud. La case
du centre est étirée pour remplir tout l’espace restant.
[Link]
[Link]
45
Annexe A. Applications graphiques (package swing)
FlowLayout. Les composants sont ajoutés les uns à la suite des autres et de la gauche vers la
droite. Dès qu’une ligne est remplie de composants (c’est-à-dire dès que la largeur du container
est atteinte, les composants restants sont ajoutés sur une ligne en dessous. Il n’y a pas d’autres
contraintes de disposition :
[Link](MyComponent);
GridLayout. Le container est découpé en une grille composée de n cases de taille égale. Le
construc- teur du GridLayout requiert en paramètres d’entrée le nombre de lignes et le nombre de
colonnes de la grille. Les composants sont ajoutés les uns à la suite des autres en remplissant
d’abord la première ligne, puis la seconde, etc. Il n’y a pas d’autres contraintes de disposition :
[Link](MyComponent);
Containers classiques
[Link](new GridLayout(4,5));
Les composants peuvent ensuite être ajoutés avec la méthode add() appropriée.
Une interface graphique consiste donc en une hiérarchie de composants telle que certains
composants sont des containers spécifiant la disposition d’autres composants. La racine de
cette
46
A.2. Composants graphiques
hiérarchie est également un container qui peut s’afficher librement (c-à-d. sans que sa
disposi- tion soit précisée dans un container). Parmi ces containers de haut niveau, on trouve la
classe [Link] qui représente une fenêtre et [Link] qui représente
une boîte de dialogue. La création d’une fenêtre suit généralement les étapes suivantes :
1. Création d’une instance de JFrame (ou d’une sous-classe).
2. Ajout des composants au panel de la fenêtre. Ce panel est accessible par la méthode
getContentPane(). On peut également attribuer à la fenêtre un nouveau panel par la mé-
thode setContentPane().
3. Calcul de la taille de la fenêtre à l’aide de la méthode pack(). Ce calcul est automatique et
prend en compte la dimension préferrée de chaque composant ainsi que leur
disposition.
4. Affichage de la fenêtre par la méthode setVisible().
Par exemple, la figure A.1 (p. 44) est une instance d’une sous-classe de JFrame :
import [Link].* ;
import [Link].* ;
public ExBouton() {
super();
JLabel label = new JLabel(”Exemple de bouton”);
JPanel panel = new JPanel(new BorderLayout());
[Link](label, [Link]);
JButton b = new JButton(” Quitter ”);
[Link](b, [Link]);
[Link](panel);
[Link]();
}
47
Annexe A. Applications graphiques (package swing)
48
import [Link].* ; ButtonGroup group = new ButtonGroup();
import [Link] ; [Link](button1);
import [Link].* ; [Link](button2);
import [Link] ; [Link](button3);
A.3.1 Evénements
Un événement graphique est représenté dans le langage Java comme un objet dont la classe
hérite de [Link]. Parmi les sous-classes de AWTEvent, on peut citer les plus
couram- ment utilisées :
● ActionEvent : Se produit lorsqu’une action est effectuée sur un composant. Ex : click sur
un bouton.
● ItemEvent : Se produit lorsqu’une sélection a été effectuée sur un composant. Ex :
cochage d’une case.
● KeyEvent : Se produit lorsque un événement provient du clavier. Ex : pression d’une
touche.
● MouseEvent : Se produit lorsque un événement provient de la souris. Ex : déplacement de
la souris.
● WindowEvent : Se produit lorsqu’une action est effectuée sur une fenêtre. Ex : click sur
l’icone de fermeture d’une fenêtre.
Des méthodes sont attachées à chacune de ces classes pour avoir accès à plus de détails sur
l’événement. On peut, par exemple, récupérer le composant source de l’événement, la position de
la souris lors du click, etc.
[Link](myActionListener);
Diagramme de classes
UML
UML (Unified Modeling Language) a été créé en 199 pour être le langage standard de modé-
lisation orienté-objet. UML contient différents diagrammes utilisés pour décrire de nombreux
aspects du logiciel. Dans le cadre de ce cours, nous utiliserons uniquement le diagramme de
classes ¹.
Le diagramme de classes représente la structure statique du logiciel. Il décrit l’ensemble
des classes qui sont utilisées ainsi que leurs associations. Il est inspiré des diagrammes Entité-
Relation utilisés en modélisation de bases de données, en y ajoutant les aspects opérationnels (les
méthodes) et quelques subtilités sémantiques (la composition, par exemple).
FIUR B.1 – Représentations UML possible d’une classe, avec ou sans les membres
55
1. le langage UML pourra être étudié en profondeur lors du cours Analyse et Conception de Systèmes
Informa- tiques de l’axe Ingénierie des Systèmes Informatiques
56
Un niveau de visibilité est également attribué à chaque membre. La visibilité d’un
membre d’une classe définit quelles autres classes y ont accès (en terme de lecture/écriture).
UML utilise 3 niveaux de visibilité :
public (noté par +), le membre est visible par toutes les classes
● privé (noté par -), le membre n’est visible par aucune classe sauf celle qui le contient
● protégé (noté par ), le membre est visible par toutes les sous-classes de celle qui le contient
(cette visibilité est expliquée ultérieurement)
Personne
+ surnom : String
nom : String
prenom : String
# dateNaissance : Date
+ calculerDureePret() : int
+ getAge() : int
La figure B.2 est un exemple d’une classe Personne avec toutes les possibilités de visibilité.
Personne
{abstract} Personne
FIUR B.3 – Deux représentations possibles pour une classe abstraite Personne
Personne
+ surnom : String
nom : String
prenom : String
# dateNaissance : Date
ageMajorite : int = 18
+ calculerDureePret() : int
+ setAgeMajorite(a : int)
+ getAge() : int
FIUR B.4 – Exemple d’un attribut et d’une méthode de classe pour la classe Personne
57
Annexe B. Diagramme de classes UML B.2. Les relations
<<interface>>
Interface
B.2.1 L’héritage
En UML, l’héritage se représente par une flèche à la pointe creuse. La figure B.6 décrit deux
classes Super-classe et Sous-classe. La classe Sous-classe hérite de la classe Super-
classe.
Super-classe
Sous-classe
B.2.2 La réalisation
La réalisation d’une interface par une classe se représente par une flèche pointillée à pointe
creuse, comme illustré dans la figure B..
<<interface>>
Interface
Classe
58
Annexe B. Diagramme de classes UML
des classes reliées qui sont impliquées dans cette association. On appelle multiplicité ce nombre
d’instances qui peut prendre les valeurs suivantes :
MultiplicitéInterprétation
1un et un seul
0..1zéro ou un
Nexactement N
M..Nde M à N
*zéro ou plus
0..*zéro ou plus
1..*un ou plus
1 manage
*
Responsable chef Collaborateur
subordonné
L’exemple de la figure B.8 décrit une association manage entre la classe Responsable et la
classe Collaborateur. Un responsable gère plusieurs collaborateurs, ses subordonnés. Un col-
laborateur est géré par un seul responsable, son chef. Les éléments subordonné et chef sont des
rôles d’association.
A 1 * B
A 1 * B
A 1 * B
La figure B.10 présente des exemples de directions, dont voici les interprétations. La première
ligne signifie que A connaît tous les B auxquels elle est associée, et réciproquement, un B connaît
le A auquel il est associé. La deuxième ligne signifie que seul le A connaît les B auxquels il est
associé, mais pas l’inverse. Finalement, dans la troisième ligne, un B connaît le A auquel il est
associé, mais pas l’inverse. En fait, ceci va impliquer la présence ou non d’un attribut a de type A
dans la classe B ou b de type B dans la classe A en fonction de la direction. Par exemple, pour la
deuxième ligne, A possède une liste d’objet de type B mais B ne possède pas d’attribut de type A.
58
B.4. Correspondance UML-Java
A 1 *B
A 1 *B
A 1 * B
A 1 * B
59
Annexe B. Diagramme de classes UML
B.4.3 Interfaces
<<interface>> interface IAffichable {
IAffichable void afficher();
}
+ afficher()
B.4.4 Héritage
Adherent
- iD : int
B.4.5 Réalisation
Image
nom : String
fichier : File
+ afficher()
+ imprimer()
B.4.6 Associations
B1 public class A1 {
A1
private B1 b1 ;
...
}
60
B.4. Correspondance UML-Java
0..1epouse
Femme public class Femme {
private Homme mari ;
...
}
61
Références
● Livres :
— Programmer en Java, e Edition, Claude Delannoy, Eyrolles, 2011
— The Java Tutorial : A Short Course on the Basics, 4th Edition, Collectif, Prentice Hall,
2006
— Effective Java, 2nd Edition, Joshua Bloch, Prentice Hall, 2008
— Java in a nutshell, th edition, David Flanagan, O’Reilly, 2005
● Sites web :
— Le site officiel Java, [Link]
— Le tutorial Java, [Link]
— l’API du JDK 1., [Link]
— Un site (français) de développeurs, [Link]
— Le site JavaWorld, [Link]
● Quelques autres liens :
— des liens en rapport avec Java, [Link]
— Tutoriaux jGuru, [Link]
— plein d’autres cours, [Link]
63