Vous êtes sur la page 1sur 116

L2

TABLE Des MATIERES

1. Chapitre1 : De la programmation procédurale à la programmation orientée objet ......... 9


1.1. Premiers langages ................................................................................................. 9
1.2 Approche procédurale/ modulaire ............................................................................... 9
1.3 Approche orientée objet.............................................................................................. 9
2. Terminologie et concepts de la programmation orientée objet .................................... 10
2.1. Notion d’objet ..................................................................................................... 10
2.2. Classe ................................................................................................................. 10
2.3. Instanciation ....................................................................................................... 11
2.4. Constructeur et destructeur.................................................................................. 11
2.5. Encapsulation ..................................................................................................... 11
2.6. Héritage .............................................................................................................. 11
2.7. Polymorphisme ................................................................................................... 12
3. Langages orientés objets ............................................................................................ 12
Chapitre 2 : Syntaxe et éléments de base en java ................................................................... 14
1. Introduction ............................................................................................................... 15
2. Structure de base d’un programme en Java ................................................................. 15
3. Les identificateurs ...................................................................................................... 16
4. Les variables .............................................................................................................. 17
4.1 Types de variables ................................................................................................... 17
4.2. La déclaration des variables .................................................................................... 19
4.3. L’affectation des variables ....................................................................................... 20
5. Les structures de contrôles ......................................................................................... 21
6. Les tableaux ............................................................................................................... 22
6.1. Propriétés des tableaux ........................................................................................... 22
6.2. Déclaration et allocation d’un tableau ...................................................................... 23
6.3. Utilisation d’un tableau .......................................................................................... 24
6.4. Initialisation d’un tableau ....................................................................................... 24
6.5. Parcours d’un tableau ............................................................................................. 25
6.6. Tableau multidimensionnel..................................................................................... 26
6.7 Passer des tableaux à des méthodes .......................................................................... 26

Enseignante : Mme I.JAOUANI Page 1


L2

7. Contrôle des acquis....................................................................................................... 27


Chapitre 3 : Classes & Objets ............................................................................................... 31
1. Introduction ............................................................................................................... 32
2. Classes et objets ......................................................................................................... 32
2.1 Déclaration d’une classe ........................................................................................... 32
2.2 Création d’un objet d’une classe : l’opérateur new ................................................... 32
3. Les variables .............................................................................................................. 33
3.1 Les variables d’objet (ou d’instance de classe).......................................................... 33
3.2 Les variables de classe .............................................................................................. 34
4. Les méthodes ............................................................................................................. 35
6.1 Utilisation des méthodes........................................................................................... 35
6.2 Les méthodes de classe ............................................................................................. 36
6.3 surcharge des méthodes ........................................................................................... 37
6.4 Le passage des paramètres ........................................................................................ 38
6.5 Une méthode particulière : la méthode « main » ...................................................... 38
7. Les constructeurs et le destructeur .................................................................................. 39
7.1. Les constructeurs ..................................................................................................... 39
7.2 Le destructeur........................................................................................................... 41
7.3 Le ramasse miettes (Garbage Collector) .................................................................. 42
8. les modificateurs d’accès ............................................................................................... 42
8.1 Les mots clés qui gèrent la visibilité des entités ........................................................ 42
8.2 Le mot clé final ....................................................................................................... 43
10. Référence aux objets .............................................................................................. 45
13. Contrôle des acquis ..................................................................................................... 46
I. Exercice 2 : Une classe pour modéliser un vecteur ......................................................... 47
Leçon N°4 : Héritage ............................................................................................................ 50
1. Introduction ................................................................................................................... 51
2. Sous-classes et Super-classes ......................................................................................... 52
2.1 Définition de sous-classe .......................................................................................... 52
2.2 L'arbre de toutes les classes ...................................................................................... 52
3. Redéfinition des méthodes ............................................................................................. 53
3.1 Surcharge et masquage ............................................................................................. 53
3.2 Redéfinition des méthodes ........................................................................................ 54

Enseignante : Mme I.JAOUANI Page 2


L2

3.3 Héritage et constructeurs .......................................................................................... 55


5. Les conversions de type ................................................................................................. 56
6. L’héritage multiple ........................................................................................................ 57
7. Résumé : Avantages de l’héritage .................................................................................. 57
8. Contrôle des acquis....................................................................................................... 57
Exercice 1 - Plaque d'immatriculation ............................................................................ 58
Exercice 2 - La classe Voiture ........................................................................................ 58
Exercice 3 - Généralisation à une classe Vehicule .......................................................... 58
Chapitre 5 : Classes abstraites et interfaces ........................................................................... 61
1. Classes abstraites ........................................................................................................... 62
2. Interfaces ....................................................................................................................... 65
2.1. Définition ............................................................................................................... 65
2.2 Utilité des interfaces ................................................................................................ 68
2.3 Règles d’implémentation d’une interface ................................................................. 68
Chapitre 6 : Le polymorphisme ............................................................................................. 71
1. Introduction .................................................................................................................. 72
2. Les bases du polymorphisme ......................................................................................... 72
3. Généralisation à plusieurs classes .................................................................................. 76
4. Redéfinition et surdéfinition .......................................................................................... 77
5. Les règles du polymorphisme en Java ............................................................................ 78
6. Contrôle des acquis....................................................................................................... 79
Chapitre 7 : Gestion des exceptions ...................................................................................... 85
1. Introduction ................................................................................................................... 86
2. Les mots clés try, catch et finally ................................................................................... 87
3. La classe Throwable ...................................................................................................... 89
4. Les classes Exception, RunTimeException et Error ...................................................... 91
5. Les exceptions personnalisées........................................................................................ 91
7. L'utilisation des exceptions ............................................................................................ 93
7. Contrôle des acquis....................................................................................................... 94

Enseignante : Mme I.JAOUANI Page 3


L2

LISTE DES FIGURES

Figure 1 : Types des variables JAVA ............................................................................................................... 17


Figure 2:Schématisation des classes Article et boisson sans héritage ................................................................ 51
Figure 3:Schématisation des classes Article et boisson avec héritage ............................................................... 51
Figure 4: Exemple de classe Abstraite ............................................................................................................. 62
Figure 5 : Hiérarchie des classes d’exception java ............................................................................................ 91

Enseignante : Mme I.JAOUANI Page 4


L2

LISTE DES TABLEAUX

Tableau 1: Types des varaiables JAVA ................................................................................. 18


Tableau 2 : Affectation des variables .................................................................................... 20
Tableau 3 : Les structures de contrôles ................................................................................. 22
Tableau 4 : les modificateurs d’accès .................................................................................... 43
Tableau 5 : Constructeurs de la classe Throwable ................................................................. 89
Tableau 6 : Méthodes de la classe Throwable ....................................................................... 90

Enseignante : Mme I.JAOUANI Page 5


L2

FICHE PEDAGOGIQUE

Programmation orientée Objet

OBJECTIFS
 Comprendre les concepts de la programmation orientée objet
 Implémenter des classes d’objets
 Créer des classes avec le principe d’héritage
PRE-REQUIS
 Algorithmique
 Atelier Programmation 1
 Atelier Programmation 2
POPULATION
 Profil : Technologie de l’informatique
 Spécialité : Tronc commun
 Niveau : Semestre 3
DEROULEMENT
 Durée : 15 semaines
 Volume horaire : 3 heures Cours/semaine
EVALUATION
 Interrogation orale
 Un devoir d’une heure
 Examen final écrit de 2 heures
MOYENS PEDAGOGIQUES
 Exposé informel
 Tableau
 Support du cours
 Exercices d’application

Enseignante : Mme I.JAOUANI Page 6


L2

Chapitre I

Enseignante : Mme I.JAOUANI Page 7


L2

Chapitre 1 : Introduction à la programmation


orientée objet

Vue d’ensemble

Le but de cette première leçon est d’introduire la programmation orientée objet et les langages
orientées objets

Objectifs
 Sensibiliser l’étudiant aux avantages de la programmation orientée objet.
 Se familiariser avec les termes de la programmation orientée objet
 Découvrir les principaux concepts de la programmation orientée objet

Durée : 1 h 30mn

Pré-requis :
 Algorithmique et structures de données 1
 Atelier de programmation 1

Enseignante : Mme I.JAOUANI Page 8


L2

1. De la programmation procédurale à la programmation orientée


objet
Un programme est composé d’un ensemble de structures de données et d’un ensemble de
traitements. L’approche de conception et de programmation a évolué au fil du temps:

1.1. Premiers langages

Premiers langages : suite d’instructions qui s’exécutent de façon linéaire (l’une après
l’autre)
 Aucune modularité
 Pas de possibilité de réutilisation

1.2 Approche procédurale/ modulaire


Le programme correspond à un ensemble de fonctions qui s’appellent entre elles
 Modularité des programmes
 Décomposition possible d’un problème complexe en plusieurs sous problèmes
 Maintenance plus facile
 Dissociation des données des fonctions qui les manipulent
 Pas de moyen / technique de spécialisation des fonctions existantes
 Nécessité de raisonner de manière hiérarchique, centralisée et temporelle.

1.3 Approche orientée objet

La modélisation objet crée une représentation informatique des éléments du monde réel
indépendamment de l’implémentation.
 Extensibilité / évolutivité
 Fiabilité : conservation de l’intégrité des données
 Les données et les fonctions sont éclatées (vision décentralisée et
nontemporelle)
 Réutilisation
 Abstraction : analyse du problème indépendamment du codage


Enseignante : Mme I.JAOUANI Page 9


L2

2. Terminologie et concepts de la programmation orientée objet

2.1. Notion d’objet

Un objet représente une entité du monde réel. Il est caractérisé par un état et un
comportement.
L’état d’un objet est l’ensemble des données qui le décrivent qu’on appelle attributs. Le
comportement décrit les traitements associés à l’objet qu’on appelle méthodes.
Un objet regroupe les données et les moyens de traitement de ces données (fonctions
membres / méthodes)
Exemples :
Objet 1 : Peugeot 206 Objet 2 : Ford Fiesta

Couleur : rouge Couleur : vert


Nombre de chevaux : 5 Nombre de chevaux : 4
Marque : Peugeot Marque : Ford
Num Immatriculation : 87654321 Num Immatriculation : 12396578
Nombre de roues : 4 Nombre de roues : 4
Vitesse maximale 260 Vitesse maximale : 220
Démarrer Démarrer
Accélérer Accélérer

2.2. Classe

Une classe d’objets est une description d’un ensemble d’objets ayant un état commun et
disposant des mêmes comportements.
Une classe représente un type abstrait de données à partir duquel il est possible de créer
différents objets.

Exemple2 : Classe versus Objet

Classe Objet Obj :

Enseignante : Mme I.JAOUANI Page 10


L2

Voiture Marque = ’’Peugeot’’


char marque [10]; Couleur = ’’rouge’’
char couleur [10]; NumMatr = 95841
int NumMatr;
Void Démarrer() ;
Void Accélérer() ;

2.3. Instanciation

Une classe représente un modèle d’objet à partir duquel on peut avoir plusieurs exemplaires
(objets). Ces objets sont appelés des instances de classe. La création d’une classe s’appelle
instanciation.

2.4. Constructeur et destructeur

Lors de la déclaration d’une instance de classe, c’est à dire lorsqu’un objet est créé, une
méthode (fonction membre) est appelée automatiquement. Cette méthode s’appelle
constructeur et a pour rôle d’initialiser l’objet de la classe en question.
Inversement, une méthode appelée destructeur est appelée automatiquement lorsque
l’instance est hors de portée (fin du programme).

2.5. Encapsulation
Mécanisme qui permet de conserver l’intégrité des données en empêchant l’accès aux
attributs par un moyen autre que les méthodes proposées : c’est le masquage de certains
éléments de la classe.
On peut distinguer dans une classe, principalement, 2 parties :
 Partie publique : Accessible par tous les composants du programme ; c’est
l’interface de la classe,
 Partie privée : Accessible uniquement par les méthodes de la classe.

2.6. Héritage

Enseignante : Mme I.JAOUANI Page 11


L2

L’héritage permet de définir les bases d’une nouvelle classe objet à partir d’une classe
existante.
Les classes obtenues par l’héritage sont appelées des classes dérivées ou classes filles, les
classes d’origine sont des classes mères ou classes de base.

2.7. Polymorphisme
Le nom de polymorphisme vient du grec et signifie qui peut prendre plusieurs formes.
Une même opération peut se comporter différemment pour différentes classes/ objets.

3. Langages orientés objets


On distingue deux types de langages orientés objets :
 Les langages purement orientés objets conçus pour appliquer intégralement les
concepts de la conception objet.
Exemple : Les langages SIMULA, SMALLTALK, JAVA
 Les langages hybrides qui viennent greffer les concepts orientés objets à des langages
procéduraux existants afin d’appliquer la philosophie orientée objets.
Exemple : le langage C++ a été obtenu en ajoutant les concepts orientés objets au
langage C permettant ainsi de préserver l’existant et de pouvoir faire une transition en
douceur de la programmation structurée à celle orientée objets.

Enseignante : Mme I.JAOUANI Page 12


L2

Chapitre II

Enseignante : Mme I.JAOUANI Page 13


L2

Chapitre 2 : Syntaxe et éléments de base en java

Vue d’ensemble

Le but de cette deuxième leçon est d’introduire la syntaxe et les éléments de base en java

Objectifs
A la fin de cette leçon, l’étudient sera capable :
 De connaitre la structure d’un programme java
 De déclarer des variables en java en utilisant les types primitifs et prédéfinies
 D’utiliser les structures conditionnelles et répétitives du langage java

Durée : 4.5 h

Pré-requis :
 Algorithmique et structures de données 1
 Atelier de programmation 1

Enseignante : Mme I.JAOUANI Page 14


L2

1. Introduction
 Un programme Java est une collection d’un ou de plusieurs fichiers source. Au moins
l’un de ces fichiers contient une classe publique unique avec une méthode unique dont
la signature est la suivante :
public static void main(String[] args)
 Chaque fichier du programme doit comprendre une classe ou bien une interface
publique et est appelé X.java, X correspond au nom de la classe ou de l’interface
publique. Chaque fichier X.java est compilé dans un fichier classe appelé X.class. Le
programme est ensuite lancé en exécutant le fichier X.class qui contient la méthode
main comprenant les instructions à exécuter.
 Cette programmation peut être effectuée à partir de la ligne de commande ou bien d’un
environnement de développement intégré IDE.

2. Structure de base d’un programme en Java

Un fichier Java est composé de :

o Une clause package facultative


o 0, une ou plusieurs instructions Import
o Une ou plusieurs définitions de classes

Toutes les instructions Java doivent apparaître au sein des méthodes et toutes les méthodes
doivent apparaître au sein d’une définition de classe.

1. package nom_package ; // clause package facultatif


2. Import java.lang.* // instruction import
3. public class MaClasse // définition de la classe MaClasse
4. {
5. public static void main(String[] args)
6. {
7. System.out.println ("Bonjour à tous");
8. } // fin de la méthode main
9. } // fin classe MaClasse

Enseignante : Mme I.JAOUANI Page 15


L2

 Le programme ci avant déclare une classe appelée MaClasse et une signature d’une
unique méthode appelée main. Les membres de la classe apparaissent entre des accolades {
}, après le nom de la classe.
 La méthode main est capable par exemple de créer des objets, évaluer des expressions,
invoquer des méthodes. Elle débute l’exécution de l’application Java.
 La méthode main est déclarée :
o public pour qu’elle soit appelable depuis n’importe où (ici depuis la JVM).
o static pour indiquer que la méthode appartient directement à la classe et elle n’est
pas associée à une instance.
o Le type de retour de la méthode main est void pour indiquer qu’elle ne retourne rien
et elle n’a pas de type de retour.
 Le seul paramètre de la méthode main est un tableau d’objets String (chaînes) référencée
avec l’attribut args.
 Le corps de la méthode est constitué par un bloc d’instructions compris entre une paire
d’accolades { }. Chaque instruction se termine par un point virgule. Dans cet exemple, le
corps de la méthode main contient une seule instruction.
 Une méthode est invoquée en utilisant la référence d’un objet (System.out :
correspondant au champ out de la classe System) et un nom de méthode println séparée par
un point. La chaîne de caractères « Bonjour à tous » est passée en argument à la méthode
println.
 Les lignes 8 et 9 contiennent des commentaires. Un commentaire qui débute par // est
appelé commentaire en une seule ligne. Un commentaire qui s’étend sur plusieurs lignes
(commentaire multi lignes) est délimité par un /* et se termine par */ . Java a introduit de
plus le commentaire de documentation, délimité par /** et */ .

3. Les identificateurs

Pour désigner un élément d’un programme (variable, objet, méthode, classe, …), on utilise
des identificateurs. Il existe des règles permettant de choisir un identificateur.

Les identificateurs en Java peuvent commencer par une lettre, par le caractère de
soulignement _ ou par le signe dollar $. Le reste du nom peut comporter des lettres ou des

Enseignante : Mme I.JAOUANI Page 16


L2

nombres mais jamais d'espaces. Un identificateur doit être différent des mots réservés du
langage Java (public, break, private, final, abstract, …).

4. Les variables

4.1 Types de variables

Dans le cadre de tous les langages de programmation, l’accès aux données est effectué via
des variables. Avec Java une variable est soit une référence à un objet, soit un type primitif.
S’il s’agit d’une référence, sa valeur est null ou bien elle contient l’adresse d’un objet
instancié.

Types Java
Types primitifs
booléen
Types numériques
Types entiers
byte
short
int
long
char
Types à virgule flottante
float
double
Types de références
type tableau
type classe
type Interface
Figure 1 : Types des variables JAVA

Le langage Java contient huit types prédéfinis ou primitifs pour fournir un support aux entiers,
flottants, booléens et caractère. Les types primitifs de Java sont :

Type Désignation Longueur Valeurs Commentaires

valeur logique : true pas de conversion possible vers


boolean 1 bit true ou false
ou false un autre type

Enseignante : Mme I.JAOUANI Page 17


L2

Byte octet signé 8 bits -128 à 127

Short entier court signé 16 bits -32768 à 32767

entouré de cotes simples dans


Char caractère Unicode 16 bits \u0000 à \uFFFF
du code Java

-2147483648 à
Int entier signé 32 bits
2147483647

virgule flottante
1.401e-045 à
Float simple précision 32 bits
3.40282e+038
(IEEE754)

virgule flottante
2.22507e-308 à
Double double précision 64 bits
1.79769e+308
(IEEE754)

-
9223372036854775808
Long entier long 64 bits
à
9223372036854775807

Tableau 1: Types des varaiables JAVA

Remarque :

 Java autorise la conversion des valeurs entières et des valeurs en virgule flottante. Le type
char peut être aussi convertit en type entier et en virgule flottante. Il est possible de forcer la
conversion de type au moyen de transtypage, en plaçant le nom de type souhaité entre
parenthèses devant la valeur à convertir.

Exemple :
float p = 3,14 ;
int x = (int) p ;
 Java est sensible à la casse.
 Les types élémentaires commencent tous par une minuscule.
 Tous les types primitifs en java possèdent des classes correspondantes à l’exception de
type booléen.

Enseignante : Mme I.JAOUANI Page 18


L2

 Pour manipuler les chaînes de caractères, Java offre une classe appelée String et une
constante chaîne de caractères.
 Java permet de manipuler une référence à un objet donné au lieu de manipuler directement
un objet tableau ou un objet de classe.

4.2. La déclaration des variables

Une variable possède un nom, un type et une valeur. La déclaration d'une variable est faite en
spécifiant son nom et son type de données.

<type> nom_de_la_variable

Une variable est utilisable dans le bloc où elle est définie. La déclaration d'une variable permet
de réserver la mémoire pour en stocker la valeur.

Exemple :
int compteur; // déclaration d’une variable compteur de type entier
int a = 5 ; // déclaration d’une variable a de type entier et initialisée à 5
String chaine; // déclaration d’une variable chaine de type String
int jour, mois, annee ; // déclaration des variables de même type séparés par une
virgule

Pour les objets, il est nécessaire en plus de la déclaration de la variable de créer un objet avant
de pouvoir l'utiliser. Il faut réserver de la mémoire pour la création d'un objet (un tableau est un
objet en Java) avec l'instruction new.

Une variable de référence ne peut contenir qu’une seule valeur. Si cette référence n’est pas
nulle, elle pointe vers l’objet auquel elle fait référence. En Java, un objet ne peut pas exister si
une variable de référence ne pointe pas vers lui.

Soit par exemple :

String pt = null;  création d’une variable de référence nulle qui ne pointe pas vers un objet.
pt

String

Enseignante : Mme I.JAOUANI Page 19


L2

String pays = new String ("France");  création d’un objet nommé pays et de type String.
Techniquement pays est le nom de la variable faisant référence à l’objet String.

pays "France"
Exemple :
String

int[] nombre = new int[10]; // création d’un tableau de type entier


MaClasse instance = new MaClasse(); // déclaration et création de l'objet instance

4.3. L’affectation des variables

Le signe = est l'opérateur d'affectation et s'utilise avec une expression de la forme :


variable = expression
L'opération d'affectation est associative de droite à gauche : il renvoie la valeur affectée.
Il existe des opérateurs qui permettent de simplifier l'écriture d'une opération d'affectation
associée à un opérateur mathématique :

Opérateur Exemple Signification

= a=10 équivalent à : a = 10

+= a+=10 équivalent à : a = a + 10

-= a-= équivalent à : a = a - 10

*= a*= équivalent à : a = a * 10

/= a/=10 équivalent à : a = a / 10

%= a%=10 reste de la division

^= a^=10 équivalent à : a = a ^ 10

<<= a<<=10 équivalent à : a = a << 10 a est complété par des zéros à droite

>>= a>>=10 équivalent à : a = a >> 10 a est complété par des zéros à gauche

>>>= a>>>=10 équivalent à : a = a >>> 10 décalage à gauche non signé

Tableau 2 : Affectation des variables

Enseignante : Mme I.JAOUANI Page 20


L2

Remarque :

Lors d'une opération sur des opérandes de types différents, le compilateur détermine le type du
résultat en prenant le type le plus précis des opérandes. Par exemple, une multiplication d'une
variable de type float avec une variable de type double donne un résultat de type double. Lors
d'une opération entre un opérande entier et un flottant, le résultat est du type de l'opérande
flottant.

5. Les structures de contrôles

Comme la plupart des langages de développement orienté objets, Java propose un ensemble
d'instructions qui permettent d'organiser et de structurer les traitements.

Instructions Désignation
While ( boolean )
Le code est exécuté tant que le booléen est vrai. Si
{
avant l'instruction while, le booléen est faux, alors le
// code a exécuter dans la boucle
code de la boucle ne sera jamais exécuté.
}
do {
Cette boucle est au moins exécuté une fois quelque soit
...
la valeur du booléen.
} while ( boolean )
for (initialisation; condition; modification)
Dans l'initialisation, on peut déclarer une variable qui
{
servira d'index et qui sera dans ce cas locale à la
...
boucle.
}
if (Boolean) {
...// code 1 à exécuter
} else if (boolean) { Le code est exécuté tant que le booléen est vrai, sinon
...// code 2 à exécuter si le booléen est vrai le code 2 est exécuté sinon le
} else { dernier code est exécuté.
...// code
}

Enseignante : Mme I.JAOUANI Page 21


L2

switch (expression) {
case constante1 :
instr11;
On ne peut utiliser switch qu'avec des types primitifs
instr12;
d'une taille maximum de 32 bits (byte, short, int, char).
break;
case constante2 :
Si une instruction case ne contient pas de break alors
...
les traitements associés au case suivant sont exécutés.
default :
...
}
break
permet de quitter immédiatement une boucle ou un
branchement. Utilisable dans tous les contrôles de flot.

continue
s'utilise dans une boucle pour passer directement à
l'itération suivante.

Tableau 3 : Les structures de contrôles

6. Les tableaux

Un tableau est une collection de variables qui portent tous le même nom et le même type.
Ces valeurs peuvent être des valeurs primitives ou des objets ou encore d’autres tableaux.
Pour faire référence à un emplacement donné, c'est-à-dire à un élément du tableau, nous
spécifions le nom du tableau et le numéro de position de cet élément particulier du tableau.

6.1. Propriétés des tableaux

Dans le cadre du langage de programmation Java, les tableaux présentent les propriétés
suivantes :

 Les tableaux sont des objets.


 Ils sont créés dynamiquement (au moment de l’exécution).
 Ils peuvent être affectés à des variables de type Object.
 Toutes les méthodes de la classe Object peuvent être appelées sur un tableau.
 Un objet tableau contient une séquence de variables qui sont toutes du même type.

Enseignante : Mme I.JAOUANI Page 22


L2

 Les variables sont qualifiés de composants du tableau.


 Si le type de composant est T, le tableau a également le type T [].
 Une variable de type tableau contient une référence à l’objet tableau.
 Le type de composant peut également avoir le type tableau.
 Un élément de tableau est un composant dont le type n’est pas un tableau.
 Un type d’élément peut être primitif ou de référence.
 La longueur d’un tableau correspond à son nombre de composants.
 La longueur d’un tableau est paramétré lors de sa création et ne peut pas être
modifiée par la suite.
 Pour être accessible, la longueur d’un tableau doit être définie comme une variable
d’instance public final.
 Les tableaux doivent être indexés par des valeurs intégrales dans un intervalle de 0
à length – 1.
 Une exception ArrayIndexOutOfBoundsException est lancée si la propriété
précédente n’est pas respectée.
 Les tableaux peuvent être copiés à l’aide de la méthode object.clone().

6.2. Déclaration et allocation d’un tableau

Un programme peut déclarer des tableaux de tout type de donnée. Chaque élément d’un
tableau qui contient un type de donnée primitif correspond à une valeur de ce type. Par
exemple, chaque élément d’un tableau de type int contient une valeur int. A l’opposé, si le
tableau contient des objets, chaque élément correspond à une référence vers ce type d’objet.
Ainsi, chaque élément d’un tableau de type String équivaut à une référence de type String
qui possède la valeur null par défaut.

Java permet de placer les crochets après ou avant le nom du tableau dans la déclaration.

int tab[] ; est équivalent à int[] tab ;

 Cette instruction permet de déclarer un tableau des entiers de taille nulle.

Les tableaux sont des objets qui occupent de la place en mémoire. Tous les objets de Java,
les tableaux compris, doivent recevoir une allocation dynamique de mémoire avec
l’opérateur new. Il faut spécifier la taille d’un tableau.

Enseignante : Mme I.JAOUANI Page 23


L2

Pour allouer 50 éléments du tableau d’entiers tab, le programme utilise l’instruction


suivante :
int tab[] = new int[50];
Cette instruction s’effectue également en deux étapes :
int tab[]; // déclaration de tableau
tab = new int[50]; //allocation de la mémoire au tableau

Une même déclaration peut réserver de la mémoire pour plusieurs tableaux de même type.
Par exemple, on déclare un tableau b de type String et 27 éléments pour le tableau x de
String :

String b [] = new String [100] , x [] = new String [27];

En combinant la déclaration et l’initialisation d’un tableau, l’instruction suivante réserve 10


éléments pour le tableau1 et 20 éléments pour le tableau2 :

double [] tableau1 = new double [10] ,


tableau2 = new double [20] ;

6.3. Utilisation d’un tableau

L’accès à un élément du tableau se fait au moyen d’un indice entier. Les indices du tableau
commencent à partir de 0.
Un objet tableau possède un champ lenght indiquant le nombre d’éléments contenus dans
un tableau. Les bornes de tableau commence de 0 et se termine par lenght – 1. Dans le cas
où l’index dépasse les bornes du tableau, une exception
ArrayIndexOutOfBoundsException est lancée. Les exceptions seront présentées un plus
tard. Un tableau de taille nulle est un tableau vide.

6.4. Initialisation d’un tableau

Java initialise chaque élément d’un tableau à 0 s’il correspond à un type de donnée primitif,
à false s’il représente une variable de type boolean ou à null s’il s’agit d’une référence
(c'est-à-dire de tout type non primitif).

Enseignante : Mme I.JAOUANI Page 24


L2

La taille du tableau n'est pas obligatoire si le tableau est initialisé à sa création. Le nombre
d’éléments de la liste d’initialisation détermine la taille de tableau. Par exemple, la
déclaration
int tableau[5] = {10,20,30,40,50};
crée un tableau de cinq éléments avec les indices 0, 1, 2, 3 et 4. Lorsque le compilateur
rencontre une liste d’éléments d’initialisation, il compte le nombre d’éléments
d’initialisation et génère automatiquement l’opérateur new qui permet de créer l’objet
tableau correspondant.

6.5. Parcours d’un tableau

int tableau[] = new int[50];


for (int i = 0; i < tableau.length ; i ++)
{
...
}

 La variable length retourne le nombre d'éléments du tableau.

Exemple : Calcul de la somme des éléments d’un tableau

public class SommeTab


{
//la méthode main marque le début d'une aplication Java
public static void main(String[] args)
{
int tableau[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int total = 0;
//ajouter la valeur de chaque élément au total
for (int compteur = 0; compteur < tableau.length; compteur++)
{
total += tableau[compteur];
System.out.println(total);
}
}
}

Enseignante : Mme I.JAOUANI Page 25


L2

6.6. Tableau multidimensionnel

Le langage Java ne prend pas directement en charge les tableaux à indices multiples. Cependant,
il permet la définition d’un tableau à un indice dont les éléments sont à leur tour des tableaux à
un indice. Dans la déclaration de ce type de tableau, toute paire de crochet représente une
dimension.
L’accès à un élément du tableau nécessite de spécifier autant de valeurs d’indices que de
dimensions. Lors de la création du tableau avec l’opérateur new, il est indispensable de spécifier
toutes les dimensions. Cependant, il est possible de ne pas spécifier toutes les dimensions mais
il faut surtout spécifier les dimensions les plus à gauche.
int [] [] tab = new int [10] [10] ; // création d’un tableau de 2 dimensions

int [] [] tab = new int [10] [] ;

int [] [] tab = new int [ ] [10] ; // la dimension n’est pas spécifiée à gauche (c’est faux)

Exemple :

Les tableaux à deux indices représentent des tables de valeurs, disposées en rangées et colonnes.
Pour identifier un élément bien déterminé d’une table, il faut en indiquer les deux indices : le
premier désigne la rangée de l’élément dans la table et le second désigne la colonne. Soit la
déclaration suivante : int b [] [] = {{1, 2},{3, 4}} ;

Les accolades regroupent les valeurs par rangées : 1 et 2 initialisent b[ 0 ] [ 0 ] et b[ 0 ] [ 1 ],


alors que 3 et 4 initialisent b[ 1 ] [ 0 ] et b[ 1 ] [ 1 ].

Colonne 0 Colonne 1
Rangée 0 b[ 0 ] [ 0 ] b[ 0 ] [ 1 ] Colonne 0 Colonne 1
Rangée 1 b[ 1 ] [ 0 ] b[ 1 ] [ 1 ]. Rangée 0 1 2
Rangée 1 3 4

indice (ou index) de colonne

indice (ou index) de rangée

Nom du tableau

Enseignante : Mme I.JAOUANI Page 26


L2

Il faut spécifier le nom du tableau sans les crochets droits pour le passer en argument à une
méthode. Par exemple, si nous déclarons le tableau tableau1 comme suit :

int tableau1 [] = new int [ 24 ] ;

alors l’appel de la méthode :

modifierTableau ( tableau1) ;

passe le tableau tableau1 à la méthode modifierTableau. En Java, chaque objet tableau connaît
sa propre taille via la variable lenght. Par conséquent, lorsqu’on passe un objet tableau à une
méthode, il n’est pas nécessaire de signifier au passage la taille du tableau.

Le nom du tableau suivi de l’indice d’un élément indiqué en argument d’une méthode permet
le passage de l’élément à la méthode. Soit par exemple :

modifierElement ( tableau1 [ 3 ]) ;

Pour qu’une méthode puisse recevoir un tableau par le biais d’un appel de méthode, la liste de
paramètres de la méthode doit spécifier un paramètre de tableau (ou plusieurs si nécessaire).
Par exemple, l’en-tête de la méthode modifierTableau qui correspond à

void modifiertableau ( int b [] )

indique que modifiertableau s’attend à recevoir un tableau d’entiers dans le paramètre b.


Comme les tableaux passent par référence, lorsque la méthode appelée utilise le nom de tableau
b, elle fait référence au tableau existant déjà chez l’appelant (correspondant au tableau tableau1
de l’appel précédent).

7. Contrôle des acquis

Exercice 1 :

Qu’affiche ce programme ?

public class Boucles


{
public static void main (String [] args)
{

Enseignante : Mme I.JAOUANI Page 27


L2
int a = 0;
do
{
System.out.println("java");
a++;
}
while(a < 5);
System.out.println("valeur de a en sortie de boucle =
" + a);
System.out.println();
int b = 0;
do
{
System.out.println("java");
b++;
}
while(a < -1);
System.out.println("valeur de b en sortie de boucle =
" + b);
System.out.println();
int c = 0;
while(c < 0)
{
System.out.println("java");
c++;
}
System.out.println("valeur de c en sortie de boucle =
" + c);
}
}

Exercice 2 :
Ecrivez des instructions Java différentes qui accomplissent chacune les tâches suivantes :

1. Affecter la somme de x et de y à z et incrémenter la valeur de x de 1 après le calcul.


(Remarque : utilisez q’une seule instruction).
2. Tester si la valeur de la variable compteur est plus grande que 10. Si elle l’est,
afficher « compteur est plus grand que 10 ».
3. Décrémenter la variable x de 1, puis la soustraire de la variable total. (Remarque :
utilisez q’une seule instruction).
4. Calculer le reste après la division de q par diviseur et affecter le résultat à q. Ecrivez
cette instruction de deux manières différentes.
5. Déclarer les variables somme et x de type int.
6. Affecter 1 à la variable x.
7. Affecter 0 à la variable somme.
8. Ajouter la variable x à la variable somme et affecter le résultat à la variable somme.
Enseignante : Mme I.JAOUANI Page 28
L2

9. Afficher « la somme vaut : », suivi de la valeur de la variable somme.


Combinez les instructions depuis la question 5 à la question 9 pour former une application Java
qui calcule et affiche la somme des entiers de 1 à 10. Utiliser une structure while pour boucler
sur les instructions de calcul et d’incrémentation. La boucle doit s’achever lorsque la valeur de
x atteint 11.
Exercice 3 : calcul de la somme des éléments d’un tableau
1. Créer un tableau d’entiers et l’initialiser aux valeurs suivantes : {1, 2, 3, 4, 5, 6, 7, 8, 9,
10.
2. Ecrire le code correspondant pour calculer la somme des valeurs contenues dans le
tableau créé.
3. Ecrire un programme qui permet d’inverser l’ordre des éléments du tableau.
Exercice 4 :
Une école supérieure propose un cours qui prépare les étudiants à l’examen de licence d’état.
Plusieurs étudiants qui ont terminé ce cours ont tenté l’examen. Naturellement, l’école s’est
renseignée à propos des résultats des étudiants à cet examen.
L’école demande d’écrire un programme qui résume les résultats. Pour une liste de 10 étudiants,
a côté de chaque nom apparaît un 1 si l’étudiant a réussi l’examen ou un 2 s’il a échoué.
Le programme doit analyser les résultats de l’examen comme suit :

1. Entrer chaque résultat du test (1 ou 2). Afficher le message « entrer résultat » à l’écran
chaque fois que le programme réclame un autre résultat.
2. Compter le nombre de résultats du test de chaque type.
3. Afficher un résumé des résultats du test indiquant le nombre d’étudiants qui ont réussi
et le nombre d’étudiants qui ont échoué.
4. Si plus de 8 étudiants ont réussi l’examen, afficher le message « Promouvoir le
cours ».

Enseignante : Mme I.JAOUANI Page 29


L2

Chapitre III

Enseignante : Mme I.JAOUANI Page 30


L2

Chapitre 3 : Classes & Objets

Vue d’ensemble

Le but de ce troisième chapitre est d’introduire les notions de classes et d’objets.


Objectifs
A la fin de cette leçon, l’étudient sera capable :
 De déclarer des classes java
 De définir les constructeurs et le destructeur
 D’exploiter le principe de surcharge des méthodes offert par le langage java
Durée : 8 h

Pré-requis :
 Algorithmique et structures de données 1
 Atelier de programmation 1
 Syntaxe et éléments de base en java

Enseignante : Mme I.JAOUANI Page 31


L2

1. Introduction
Comme le langage Java est "Orienté Objet", il est entièrement basé sur la notion
d'encapsulation, c'est-à-dire qu’il permet de définir des classes qui contiennent des
membres. Les membres sont soit des champs soit des méthodes. L'instance de la classe
(appelé objet) est alors implicitement passée en paramètre à la méthode.
Les champs (parfois appelé attribut) sont des variables qui définissent des caractéristiques
propres à chaque objet (variables d’instance) ou à un groupe d’objets de la classe (variables
de classe). Ces variables ont une portée différente suivant l’endroit où elles sont déclarées.
Les méthodes sont des fonctions qui définissent les comportements des objets de la classe.
Contrairement au C/C++, Java est « purement » orienté objet, c’est-à-dire qu’il est
impossible de définir des fonctions autres que des méthodes.

2. Classes et objets

2.1 Déclaration d’une classe


En Java, la déclaration d’une classe est très simple :
Fichier "Point2D.java"
class Point2D {
}
Il est possible d’imbriquer des classes dans des classes (Les classes intérieures).

2.2 Création d’un objet d’une classe : l’opérateur new

Pour qu'un objet puisse réellement exister au sein de la machine, il faut qu'il puisse stocker
son état dans une zone de la mémoire. La seule manière de créer un objet d’une classe en
Java est d’utiliser l’opérateur new. Cet opérateur doit être suivi du nom de la classe dans
lequel l’objet est crée. L’opérateur new détermine la place mémoire nécessaire à la
définition d’un objet. La création d'un objet est parfois appelée instanciation.
Voici quelques exemples d’instanciation d’objets :
String chaine = new String ();
Point2D point = new Point2D ();
String chaine2 = new String ("Bonjour");
Les opérations réalisées par new :

Enseignante : Mme I.JAOUANI Page 32


L2

L’appel à l’opérateur new déclenche une série d’actions :


 création de l’objet d’une classe
 allocation de la mémoire nécessaire a cet objet
 appel d’une méthode particulière définie dans la classe : le constructeur.

3. Les variables

3.1 Les variables d’objet (ou d’instance de classe)


Ces variables sont déclarées dans une classe mais en dehors d’une méthode et sont
globales pour tous les objets de la classe.
Fichier "Point2D.java"
class Point2D
{
double x,y;
}
Fichier "Cercle.java"
class Cercle
{
Point2D centre = new Point2D();
double rayon;
Color couleur;
}
Fichier "Program.java"
class Program
{
Public static void main (args[])
{
Cercle C1 = new Cercle() ;
Cercle C2 = new Cercle() ;
C1.centre.x = 3.45;
...
C2.centre.y = 3.56;
...

Enseignante : Mme I.JAOUANI Page 33


L2

C1.couleur = Color.red ;
C2.couleur = Color.red ;
...
}
}
Remarque : On crée un objet Point2D. Sans cette création, le programme génère une
erreur (mémoire non allouée) lors de l’affectation d’un des champs d’un objet de la classe.

3.2 Les variables de classe

Ces variables sont globales pour une classe et pour toutes les instances de cette classe.
Les variables de classe sont utiles pour faire communiquer entre eux différents objets
d’une même classe ou pour définir des propriétés communes à un groupe d’objets de la
même classe. Pour différencier les variables d’objet des variables de classe on utilise le
mot-clé static.

Fichier "Point2D.java"
class Point2D
{
double x,y;
}
Fichier "Cercle.java"
class Cercle
{
Point2D centre = new Point2D();
double rayon;
static Color couleur;(*)
}
Fichier "Program.java"
class Program
{
public static void main (args[]) {
Cercle C1 = new Cercle() ;
Cercle C2 = new Cercle() ;
C1.centre.x = 3.45;
Enseignante : Mme I.JAOUANI Page 34
L2

C1.centre.y = 3.56;
Cercle.couleur = Color.red ;(**)
...
}
Remarque :
* Le champ couleur est une variable de classe
** On applique une couleur à tous les objets de la classe.

4. Les méthodes

6.1 Utilisation des méthodes


La définition du comportement d’un objet passe par la création de méthodes (ensemble
d’instructions Java exécutant certaines tâches). Les méthodes sont définies dans une classe
et accessibles seulement dans cette classe. Contrairement au C++, Java ne possède pas de
fonctions définies en dehors des classes. L’appel des méthodes est similaire à la référence
aux variables d’instances: les appels de méthodes utilisent aussi la notation pointée.
Ajoutons une méthode Move (qui permet de déplacer un objet de la classe Cercle) à notre
classe Cercle.

Fichier "Point2D.java"

class Point2D {
double x,y;
}

Fichier "Cercle.java"

class Cercle {
Point2D centre = new Point2D ();
double rayon;
Color couleur;
void Move(double x ,double y) {
centre.x = centre.x + x;

Enseignante : Mme I.JAOUANI Page 35


L2

centre.y = centre.y + y;
}
}

Fichier "Program.java"

class Program {
public void main (args[]) {
Cercle C = new Cercle() ;
C.centre.x = 3.45;
C.centre.y = 3.56;
C.Move(4.0,3.0) ;
...
}
}

(*) : Définition de la méthode « Move »


(**) : Appel de la méthode Move appliquée à l’objet de la classe cercle
Vous aurez sans doute remarqué l'utilisation de mot clé void. Celui-ci sert à définir un type de
retour nul (sans valeur) pour la méthode. Si une méthode doit retourner une valeur (non
nulle), il faut spécifier son type à cet endroit précis de la définition de la méthode.

6.2 Les méthodes de classe

Comme les variables de classe, les méthodes de classe (à déclarer en static) s’appliquent à
la toute classe et non à ses instances. Ces méthodes servent surtout à grouper au même
endroit, dans une classe, des méthodes à caractère général.
Par exemple, la classe Math définie dans java.lang contient de nombreuses méthodes
de classe. Il n’existe pas d’instance de la classe Math, mais on peut utiliser directement ses
méthodes. Par exemple la méthode max(…) :
int a = Math.max (x, y) ;

Enseignante : Mme I.JAOUANI Page 36


L2

6.3 surcharge des méthodes

Le polymorphisme autorise la définition de plusieurs méthodes ayant le même nom dans la


mesure où les paramètres sont différents (nombres de paramètres différents ou types
différents).
Ainsi, pour définir un déplacement du cercle uniquement en x, vous pouvez définir une autre
méthode Move n’ayant qu’un seul paramètre. Il est également possible de définir une
méthode Move qui effectue un déplacement par défaut en x et en y.
Fichier "Cercle.java"
class Cercle {
Point2D centre = new Point2D() ;
double rayon ;
Color couleur ;
void Move(double x ,double y)
{
centre.x = centre.x +x ;
centre.y = centre.y +y ;
}
void Move(double x)
{
centre.x = centre.x +x ;
}
void Move()
{
centre.x = centre.x + 1.0 ;
centre.y = centre.y + 1.0 ;
}
}
Fichier "Program.java"
class Program {
public static void main (args[]) {
Cercle C = new Cercle() ;
C.centre.x = 3.45 ;
C.centre.y = 3.56 ;

Enseignante : Mme I.JAOUANI Page 37


L2

C.Move(4.0,3.0) ;
...
C.Move(2.0) ;
...
for (int i=1;i<=10;i++)
C.Move() ;
}
}
Appel des trois méthodes Move appliquée à l’objet C de la classe Cercle

6.4 Le passage des paramètres

Lorsque vous appelez une méthode dont les arguments comportent un ou plusieurs objets,
les variables qui sont passées au corps de la méthode sont passées par référence. Ceci
signifie qu’il n’y a pas de copie locale (à la méthode) de l’objet passé en paramètre. Par
conséquent, toute manipulation de l’objet à l’intérieur de la méthode affecte l’objet original.
Cette règle de passage des paramètres s’applique à tous les objets ainsi qu’aux tableaux.
Seul les variables de type simple (entiers, réels, booléens et caractères) sont passées par
valeur (on recopie localement la variable et on travaille sur cette copie).

6.5 Une méthode particulière : la méthode « main »

Comme nous l'avons déjà dit en présentant le langage, on lance l'exécution d'un programme
Java en démarrant une machine virtuelle Java avec, en paramètre, le nom de la classe de
démarrage. Cette classe doit impérativement contenir une méthode main. Une fois que la
machine virtuelle s'est mise en place, elle lance le programme proprement dit par la première
instruction de la méthode main, et ce, sans instancier d'objet à partir de la classe de
démarrage. Ceci est possible car la méthode main est déclarée static : c'est à dire qu'elle
existe sans qu'il y ait eu instanciation. La tâche principale de cette méthode est alors
d'instancier des objets sur différentes classes afin que le programme puisse s’exécuter.
Comme la méthode main existe indépendamment de toute instance de classe, si elle doit
utiliser des attributs ou des méthodes de la classe, il faut que ces champs soient eux aussi
déclarés static, sans quoi, ils n'existent pas. Plus formellement, les méthodes déclarées
statiques, sur une classe, ne peuvent manipuler que des champs statiques.

Enseignante : Mme I.JAOUANI Page 38


L2

Notons au passage que la méthode main admet en paramètre un tableau de chaînes de


caractères ("String argv[]"). Celui-ci contient les éventuelles options spécifiées sur la
ligne de commande lors du lancement de la machine virtuelle. Pour connaître la taille du
tableau, il suffit de récupérer la valeur renvoyée par argv.length. A titre d'information, le
nom du paramètre peut être n'importe quel nom, mais on utilise souvent argv, repris de la
terminologie du langage C/C++.
Fichier "Start.java"
class Start {
static int a =3;
static public void main(String argv[])
{
a =a +5;
System.out.println("a^2 ="+Square(a));
}
static int Square(int value)
{
return value*value;
}
}

7. Les constructeurs et le destructeur

7.1. Les constructeurs

De manière basique, on peut dire qu'un constructeur est une méthode, d'une classe donnée,
servant à créer des objets. Contrairement aux méthodes, un constructeur n'a pas de type de retour
et il a nécessairement le même nom que la classe dans laquelle il est défini. De même que les
autres méthodes, les constructeurs acceptent la surcharge. L'exemple suivant propose donc
quelques constructeurs pour nos classes déjà étudiées.
Fichier "Point2D.java"
class Point2D {
double x,y;
Point2D () { x=0.0, y=0.0 ; }
Fichier "Cercle.java"

Enseignante : Mme I.JAOUANI Page 39


L2
class Cercle
{
Point2D centre ;
double rayon;
Color couleur;
void Move(double x ,double y)
{
centre.x = centre.x + x;
centre.y = centre.y + y;
}
Cercle ()
{
centre = new Point2D();
rayon = 2.0 ;
couleur = Color.red ;
}
Cercle (double r, Color c)
{
centre = new Point2D();
rayon =r ;
couleur =c ;
}
}
Fichier "Program.java"
class Program {
public static void main (args[]) {
Cercle C1 = new Cercle() ;
Cercle C2 = new Cercle(3.0,Color.blue) ;
C1.centre.x = 3.45;
C1.centre.y = 3.56;
C1.Move(4.0,3.0) ;
...
C2.Move(3.4,3.6) ;
...

Enseignante : Mme I.JAOUANI Page 40


L2
}
}
 Le constructeur de la classe Point2D initialise les valeurs de x et de y.
 On définit deux constructeurs d’objets de la classe Cercle.
 Notez que l’on construit un objet de la classe Point2D dans chacun des
constructeurs.
 C1 est un cercle de couleur rouge et de rayon 2.
 L’utilisateur de la classe Cercle choisit le rayon et la couleur de C2 (ici 3 et bleue).
Sur cet exemple, on peut remarquer qu’un constructeur peut créer des objets qu'il
utilise. On s'aperçoit également que les constructeurs servent principalement à
définir l'état initial des objets instanciés. Il est bien sûr possible d’initialiser les
variables lors de leur déclaration, mais le constructeur permet de créer des objets «
sur mesure ».

Deux règles fondamentales sur les constructeurs :
 Si aucun constructeur n'est spécifié, dans la définition de la classe, un constructeur par
défaut vous est obligatoirement fourni, celui-ci n'admettant aucun paramètre.
 Si vous en définissez au moins un, le constructeur par défaut (qui n'admet pas
de paramètres) n'est plus fourni. Si vous en avez utilité il vous faudra alors le
définir explicitement

7.2 Le destructeur
Nous venons donc de voir que des constructeurs pouvaient être fournis pour permettre la
création d'objets. Parallèlement, un destructeur (et un seul) peut être défini, pour être utilisé
lors de la destruction de l'objet. Celui-ci doit forcément se nommer finalize, il ne prend
aucun paramètre et ne renvoie aucun type (void). Voici un petit exemple :
class Point2D {
...
void finalize()
{
System.out.println("Objet point (2D) détruit");
}
...
}
Enseignante : Mme I.JAOUANI Page 41
L2

7.3 Le ramasse miettes (Garbage Collector)

Un programme Java a besoin de mémoire pour pouvoir s'exécuter (en règle général, plus il en
a, mieux c'est). Comme on l'a déjà vu, l’opérateur new se charge d'allouer de la mémoire à la
demande. Une conséquence évidente est que si l'on ne libère pas la mémoire des objets
devenus inutiles, on peut rapidement en manquer. Le ramasse-miettes (Garbage Collector) se
charge de repérer ces objets inutiles, et de libérer la mémoire qu'ils utilisent inutilement. Il
opère de façon totalement automatisé, et dans la quasi totalité des cas, vous n'avez pas à vous
en soucier. N'oubliez pas que vous avez la possibilité de définir, par l'intermédiaire d’un
destructeur, des actions à effectuer en cas de destructions d'objet.

8. les modificateurs d’accès

Ils se placent avant ou après le type de l'objet mais la convention veut qu'ils soient placés
avant. Ils s'appliquent aux :
 Classes,
 et/ou aux méthodes,
 et/ou aux attributs.
Ils ne peuvent pas être utilisés pour qualifier des variables locales : seules les variables
d'instances et de classes peuvent en profiter.
Ils assurent le contrôle des conditions d'héritage, d'accès aux éléments et de modification
de données par les autres objets.

8.1 Les mots clés qui gèrent la visibilité des entités

De nombreux langages orientés objet introduisent des attributs de visibilité pour réglementer
l'accès aux classes et aux objets, aux méthodes et aux données.
Dans Java, il y a quatre modificateurs qui peuvent être utilisés pour définir les attributs de
visibilité des entités (classes, méthodes ou attributs):
 private,
 protected,
 public
 default (ou l’absence de tout modificateur).

Leur utilisation permet de définir des niveaux de protection différents.

Enseignante : Mme I.JAOUANI Page 42


L2

Modificateur Rôle
Public Une variable, méthode ou classe déclarée public est visible par tous les
autres objets.
Une seule classe public est permise par fichier et son nom doit correspondre
à celui du fichier.
Dans la philosophie orientée objet aucune donnée d'une classe ne devraient
être déclarée publique : il est préférable d'écrire des méthodes pour la
consulter et la modifier
par défaut : Il n'existe pas de mot clé pour définir ce niveau, qui est le niveau par défaut
package lorsqu'aucun modificateur n'est précisé.
friendly Cette déclaration permet à une entité (classe, méthode ou variable) d'être
visible par toutes les classes se trouvant dans le même package.
protected Si une classe, une méthode ou une variable est déclarée protected, seules les
méthodes présentes dans le même package que cette classe ou ses sous
classes pourront y accéder.
On ne peut pas qualifier une classe avec protected.
Private C'est le niveau de protection le plus fort. Les composants ne sont visibles
qu'à l'intérieur de la classe :
ils ne peuvent être modifiés que par des méthodes définies dans la classe
prévues à cet effet.
Les méthodes déclarée private ne peuvent pas être en même temps déclarée
abstract car elles ne peuvent pas être redéfinies dans les classes filles.

Tableau 4 : les modificateurs d’accès

8.2 Le mot clé final

Le mot clé final s'applique aux variables de classe ou d'instance, aux méthodes et aux
classes. Il permet de rendre l'entité sur laquelle il s'applique non modifiable une fois qu'elle
est déclarée pour une méthode ou une classe et initialisée pour une variable.
Une variable qualifiée de final signifie que la valeur de la variable ne peut plus être modifiée
une fois que celle ci est initialisée. On ne peut pas déclarer de variables final locale à une
méthode.

Enseignante : Mme I.JAOUANI Page 43


L2

Exemple :

public class Constante2 {


public final int constante;
public Constante2() {
this.constante = 10;
}
}

Une fois la variable déclarée final initialisée, il n'est plus possible de modifier sa valeur.
Une vérification est opérée par le compilateur.

Exemple :

public class Constante1 {


public static final int constante = 0;
public Constante1() {
this.constante = 10;
}
}

La compilation, nous donne:

C:\>javac Constante1.java
Constante1.java:6: cannot assign a value to final variable constante
this.constante = 10;
^
1 error

Les constantes sont qualifiées avec les modificateurs final et static.


Exemple :
public static final float PI = 3.141f;
Une méthode déclarée final ne peut pas être redéfinie dans une sous classe.
Une méthode possédant le modificateur final pourra être optimisée par le compilateur car
il est garanti qu'elle ne sera pas sous classée.

Enseignante : Mme I.JAOUANI Page 44


L2

Lorsque le modificateur final est ajouté à une classe, il est interdit de créer une classe
qui en hérite.

10. Référence aux objets


Même si la manipulation des références aux objets reste transparente pour le programmeur
Java, il est intéressant d’en comprendre le mécanisme. Examinons un programme très
simple :

Fichier "TestReference.java"
class TestReference
{
public static void main (args[])
{
Cercle C1, C2 ;
C1 = new Cercle();
C2 =C1;
C1.rayon = 3.0;
System.out.println ("r1 = "+C1.rayon);
System.out.println ("r2 = "+C2.rayon);
}
}
à l’écran
r1 = 3.0
r2 = 3.0
Dans la première partie du programme, on déclare deux variables de type Cercle (C1 et C2),
on crée un objet Cercle affecté à C1 et on affecte à C2 la valeur de C1. Comme on peut le
constater par le résultat à l’écran, la variable d’instance x a été modifiée pour les deux objets.
L’affectation de la valeur de C1 à C2 n’a pas créé un nouvel objet mais simplement une
référence à l’objet pointé par C1 (Cf. figure ci-dessous). Pour créer deux objets distincts,
il faut utiliser l’opérateur new pour chacun des objets.
Objet Cercle

Enseignante : Mme I.JAOUANI Page 45


L2

C1 centre.x : 0.0
centre.y : 0.0
C2 rayon = 3.0
couleur …

L’utilisation des références prend toute son importance lorsque les arguments sont
transmis aux méthodes.

13. Contrôle des acquis

Exercice 1 :

Il s'agit de modéliser un segment de droite dont les valeurs des deux extrémités sont entières.
Si on échange les deux extrémités, on considère qu'il s'agit encore du même segment. Les
opérations que l'on souhaite faire sur ce segment sont :

 calculer sa longueur
 savoir si un entier donné se trouve sur le segment (c'est-à-dire s'il est compris entre la
plus petite et la plus valeurs des extrémités du segment).

Ecrire un programme qui contient :

 une classe Segment comportant


o deux attributs de type int, extr1 et extr2, représentant les coordonnées (entières)
des extrémités d'un segment sur un axe
o une méthode nommée ordonne échangeant éventuellement les valeurs des
extrémités du segment de telle sorte que la valeur de extr1 soit au plus égale à la
valeur de extr2.
o une méthode retournant la longueur du segment
o une méthode dont le prototype est :

Enseignante : Mme I.JAOUANI Page 46


L2

boolean appartient(int x); indiquant si le point de coordonnée x appartient ou


non au segment

o une méthode redéfinissant la méthode :

public String toString()


Celle-ci décrira une instance de Segment sous la forme d'une chaîne de caractères (par
exemple, le segment d'extrémités -35 et 44 pourra être transformé en la chaîne de caractères :
"segment [-35, 44]") (la plus petite extrémité est toujours indiquée à gauche). La méthode
"retournera" (return...) cette chaîne.
Une classe EssaiSegment testant la classe Segment et comportant une méthode main à
laquelle on devra fournir trois paramètres entiers par la ligne de commande : origine et
extrémité d'un segment et coordonnée d'un point dont on voudra savoir s'il appartient ou non
au segment. On utilisera nécessairement la méthode toString lorsqu'on voudra écrire le
segment sur la sortie standard (l'écran).

Exercice 2 : Une classe pour modéliser un vecteur

Il s'agit de modéliser un vecteur de Z2 dont l'origine est en (0, 0) (un tel vecteur est donc
caractérisé par deux nombres entiers relatifs). Les opérations que l'on souhaite faire sur ce
segment sont :

 calculer sa longueur, par une méthode d'instance sans paramètre, nommée longueur, et
qui retourne cette longueur sous forme d'un double
 savoir si le vecteur concerné est ou non plus petit qu'un autre un autre vecteur donné ;
on écrira pour cela une méthode d'instance nommée plusPetitQue qui recevra en
paramètre l'autre vecteur et qui retournera une variable de type boolean
 additionner au vecteur concerné un autre vecteur ; on écrira pour cela une méthode
d'instance nommée addition qui recevra en paramètre l'autre vecteur et qui ne retournera
rien
 additionner deux vecteurs donnés ; on écrira pour cela une méthode statique nommée
aussi addition (en utilisant ainsi la possibilité de la surcharge) qui recevra en paramètres
les deux vecteurs à additionner et qui retournera le résultat sous forme d'un objet de type
Vecteur
 une méthode redéfinissant la méthode :

Enseignante : Mme I.JAOUANI Page 47


L2

public String toString()


Celle-ci décrira une instance de Vecteur sous la forme d'une chaîne de caractères (par
exemple, le vecteur de composantes 1 et 2 pourra être décrit par la chaîne de
caractères : "vecteur (1, 2)"). La méthode retournera cette chaîne.

On créera une classe EssaiVecteur contenant une méthode main pour tester la classe Vecteur.
Les composantes des vecteurs à traiter dans les tests pourront être indiquées sur la ligne de
commande.

Enseignante : Mme I.JAOUANI Page 48


L2

Chapitre IV

Enseignante : Mme I.JAOUANI Page 49


L2

Chapitre 4 : Héritage

Vue d’ensemble

Le but de cette quatrième leçon est d’introduire le principe d’héritage.

Objectifs
A la fin de cette leçon, l’étudiant sera capable de :
 Comprendre le principe d’héritage
 Comprendre l’héritage simple
 Définir des constructeurs de la classe dérivée
 Utiliser la redéfinition de fonctions dan/s les classes dérivées

Durée : 6 h

Pré-requis :
 Algorithmique et structures de données 1
 Atelier de programmation 1
 Classes et objets

Enseignante : Mme I.JAOUANI Page 50


L2

1. Introduction
L’héritage est une technique née du besoin de raffinement qui correspond à la situation suivante
: on dispose d'une classe A achevée, opérationnelle, définissant des objets satisfaisants, et il
nous faut définir une classe B qui en est une extension : les objets B ont tout ce qu'ont les objets
A plus quelques variables et méthodes ajoutées et/ou quelques méthodes
« améliorées » (on dira redéfinies).
Imaginons, par exemple, qu'on dispose d'une classe Article pour représenter les articles
caractérisés par le nom, le prix et la quantité et qu'il nous faille une classe Boisson dont les
instances sont des articles qui ont en plus un volume. Ces instances comportent donc tout ce qui
fait un article et, en plus la caractéristique Volume.
Si nous ne disposions que des outils expliqués dans les chapitres précédents, nous devrions
définir la classe Boisson en y dupliquant les informations qui se trouvent dans la définition de
la classe Article.
Classe Boisson
Classe Article
Nom
Nom Prix
Prix Qualité

Figure 2:Schématisation des classes Article et boisson sans héritage

Le mécanisme de l'héritage permet d'éviter cette duplication, en nous laissant déclarer dès le
commencement que la classe Boisson étend la classe Article et en possède donc tous les
attributs. De cette manière, il ne nous reste à définir que les membres spécifiques que la
deuxième classe (que nous appellerons la sous-classe) ajoute à la première (la super-classe).

Classe Article
Super-classe
Nom
Prix

Classe Boisson Sous-classe

Volume

Figure 3:Schématisation des classes Article et boisson avec héritage

Enseignante : Mme I.JAOUANI Page 51


L2

2. Sous-classes et Super-classes

2.1 Définition de sous-classe

L'héritage est le mécanisme qui consiste à définir une classe nouvelle, dite classe dérivée
ou sous-classe, par extension d'une classe existante, appelée sa classe de base ou super-
classe. La sous-classe possède d'office tous les membres de la super-classe, auxquels elle
ajoute ses membres spécifiques.
L'héritage est indiqué par l'expression « extends SuperClasse » écrite au début de la
définition d'une classe.
Par exemple, définissons la classe Pixel comme sous-classe de la classe Point qui nous a
déjà servi d'exemple. Un pixel est un point, étendu par l'ajout d'une variable d'instance qui
représente une couleur (Color est une classe définie dans le paquet java.awt) :

class Point {
class principal{
int x, y;
Pixel pix = new Pixel();
...
pix.x = 2;
}
class Pixel extends Point { pix.y = 3;

Color couleur; pix.couleur = Color.red;


}
...
}

Avec la définition précédente, un Pixel se compose de trois variables d'instance : x et y,


héritées de la classe Point, et couleur, une variable d'instance spécifique. Ces trois variables
sont membres de plein droit de la classe Pixel.
Pour pix, un objet de classe, on peut écrire pix.x et pix.y exactement comme on peut écrire
pix.couleur.

2.2 L'arbre de toutes les classes

En Java, l'héritage est simple : chaque classe possède au plus une super-classe directe. En
fait, il y a une classe particulière, nommée Object, qui n'a pas de super-classe, et toutes les
autres classes ont exactement une super-classe directe. Par conséquent, l'ensemble de toutes
les classes constitue une unique arborescence dont la racine est la classe Object.

Enseignante : Mme I.JAOUANI Page 52


L2

Ainsi, les variables et méthodes qui composent un objet ne sont pas toutes définies dans la
classe de celui-ci : il y en a une partie dans cette classe, une partie dans sa super-classe, une
autre partie dans la super-classe de la super-classe, etc.
Un message ayant été envoyé à un objet, la méthode correspondante doit être recherchée
dans la classe de celui-ci ou, en cas d'échec, dans la super-classe de celle-là, puis dans la
super-classe de la super-classe, et ainsi de suite, en remontant le long de la branche de l'arbre
d'héritage, jusqu'à trouver une classe dans laquelle on a prévu de répondre au message en
question.

3. Redéfinition des méthodes

3.1 Surcharge et masquage

Que se passe-t-il lorsque des membres spécifiques de la sous-classe ont le même nom
que des membres hérités ? Deux cas :
1. Si les entités qui ont le même nom ont des rôles ou des signatures différentes,
alors c'est un cas de surcharge et il est traité comme s'il s'agissait de deux membres
de la même classe.

2. S'il s'agit au contraire de deux entités ayant le même rôle et, dans le cas des
méthodes, la même signature alors il y a masquage : dans la sous-classe, le membre
spécifique masque le membre hérité.

Il y a plusieurs manières d'accéder à un membre masqué. Imaginons par exemple qu'on a


introduit une mesure de qualité dans les points, et aussi une notion de qualité dans les pixels,
ces deux notions n'ayant pas de rapport entre elles :

class Point { class Pixel extends Point {

int x, y; Color couleur;

int qualite; int qualite;

... ...

} }

Enseignante : Mme I.JAOUANI Page 53


L2

Dans ces conditions, à l'intérieur d'une méthode de la classe Pixel, les expressions qualite
et this.qualite désignent le membre qualite spécifique de la classe Pixel. Mais les
expressions super.qualite et ((Point) this).qualite désignent toutes deux le membre qualite
hérité de la classe Point.

3.2 Redéfinition des méthodes

La sous-classe étant une extension, c'est-à-dire une « amélioration », de la super-classe, les


objets de la sous-classe doivent répondre à tous les messages auxquels répondent les objets
de la super-classe, mais il est normal qu'il y répondent de manière « améliorée » : beaucoup
de méthodes de la sous-classe font les mêmes choses que des méthodes correspondantes de
la super-classe, mais elles le font « mieux », c'est-à-dire en prenant en compte ce que les
objets de la sous-classe ont de plus que ceux de la super-classe.

Exemple: la méthode toString :


class Pixel extends Point {
class Point {
Color couleur;
int x, y;
...
...
public String toString() {
public String toString() {
return "[" + super.toString() +
return "(" + x + "," + y +
";" + couleur + "]";
")";
}
}
}

Il est facile de comprendre pourquoi la réponse à un appel comme unPixel.toString() peut être
vue comme une « amélioration » de la réponse à unPoint.toString() : si unPoint représente un
point et unPixel un pixel, les expressions :
System.out.println(unPoint);
System.out.println(unPixel);

affichent, par exemple


(10,20)
[(30,40);java.awt.Color.red]

Contraintes de la redéfinition des méthodes

Enseignante : Mme I.JAOUANI Page 54


L2

1. On ne peut pas profiter de la redéfinition d'une méthode pour en restreindre


l'accessibilité : la redéfinition d'une méthode doit être au moins « aussi publique » que
la définition originale. En particulier, la redéfinition d'une méthode publique doit être
qualifiée public.
2. La signature de la redéfinition d'une méthode doit être identique à celle de la méthode
héritée. La signature d'une méthode se compose de trois éléments :
 le nom de la méthode,
 la suite des types de ses arguments,
 le fait que la méthode soit ordinaire (d'instance) ou static.
3. On notera bien que le type du résultat renvoyé par une méthode ne fait pas partie de
la signature de celle-ci. Dans ces conditions, sous Java 5 :
 une définition de méthode est une redéfinition si et seulement si la signature est
identique à celle d'une méthode héritée, indépendamment du type du résultat,
 si une définition est une redéfinition, alors le type du résultat de la redéfinition doit

être identique au type du résultat de la méthode héritée.

3.3 Héritage et constructeurs

L'initialisation d'un objet d'une sous-classe implique son initialisation en tant qu'objet de la
super-classe. Autrement dit, tout constructeur de la sous-classe commence nécessairement
par l'appel d'un constructeur de la super-classe.
Si le programmeur n'a rien prévu, ce sera le constructeur sans arguments de la super- classe,
qui doit donc exister. Mais on peut expliciter l'appel d'un constructeur de la super- classe
par l'instruction :
super(arguments);

Si elle est présente, cette instruction doit être la première du constructeur de la sous- classe.
Par exemple, si la classe Point n'a qu'un constructeur, à deux arguments :
Class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
...

Enseignante : Mme I.JAOUANI Page 55


L2
}

Alors le programmeur est obligé d'écrire un constructeur pour la classe Pixel, comme ceci :
class Pixel extends Point {
Color couleur;
Pixel(int x, int y, Color couleur) {
super(x, y);
this.couleur = couleur;
}
...
}

5. Les conversions de type


On distingue le « Upcasting » du « Downcasting ».
Supposons une classe abstraite A et deux classes dérivées de cette classe abstraite B et C. Les
classes B et C peuvent être traitées comme des classes A, on peut donc écrire :
B b ;
b = new B (…) ;
A a ;
a = b ;

 Une sous-classe peut toujours être convertie dans le type de sa super-classe ;


 Une fois convertie dans ce sens, on ne peut accéder qu’aux champs définis dans la
super-classe ;
 Les méthodes surchargées de la sous-classe peuvent toujours être appelées.
Dans le sens contraire, un objet de la classe A peut être converti en un objet de la classe
B uniquement s’il a été défini au départ comme un objet de B et non de C. Dans ce cas
(« Downcasting »), on utilise une syntaxe particulière (la même qu’en C/C++) :

B b ;
b = (B)a ;

Enseignante : Mme I.JAOUANI Page 56


L2

Pour savoir à quelle classe appartient un objet, on utilise l’opérateur « instanceof » qui
renvoie la valeur true ou false. Exemple :
if (a instanceof B) {
… ;
}

6. L’héritage multiple
La forme d’héritage étudiée précédemment s’appelle « l’héritage simple ». Dans un tel héritage,
chaque classe Java a une seule super-classe directe. Dans d’autres langages (notamment en
C++), les classes peuvent avoir plusieurs super-classes. Elles héritent alors de la combinaison
des variables et des méthodes de toutes leurs super-classes. Cela s’appelle
« l’héritage multiple ». Il s’agit d’un mécanisme puissant mais très complexe qui alourdit
souvent le code. Pour cette raison, Java se limite à l’héritage simple. Nous verrons bientôt qu’il
est possible de simuler l‘héritage multiple sans en avoir les inconvénients grâce au concept
d’interface.

7. Résumé : Avantages de l’héritage


Le premier point important est que l'héritage supprime, en grande partie, les redondances dans
le code. Une fois la hiérarchie de classes bien établie, on localise en un point unique les sections
de code (celles-ci restant à tous moments accessibles grâce au mot clé super).
La seconde chose importante (en considérant que la hiérarchie de classes a été bien pensée), est
qu’il est possible de rajouter facilement une classe, et ce à moindre coût, puisque l'on peut
réutiliser le code des classes parentes.
Dernier point, si un comportement n’a pas été modélisé dans une classe donnée, et qu’il est
nécessaire de le rajouter, une fois l'opération terminée, ce comportement sera directement
utilisable dans l'ensemble des sous-classes de la classe en question.

8. Contrôle des acquis

Enseignante : Mme I.JAOUANI Page 57


L2

Exercice 1 - Plaque d'immatriculation

On veut modéliser des numéros de plaques d'immatriculation en séparant le code du


département des autres informations.

1. Écrire une classe Immatriculation contenant 2 champs codeDepartement et serie


représentant respectivement le code du département (penser aux codes 2A et 2B pour
la Corse) et la séquence de chiffres et de lettres qui le précède.
2. Écrire le constructeur initialisant prenant en paramètres les valeurs des champs
précédents, ainsi que les méthodes toString(), getSerie() et getCodeDepartement().
3. Écrire la méthode getDepartement() qui retourne le nom du département en toutes
lettres.

Exercice 2 - La classe Voiture

On souhaite maintenant représenter des voitures. Les informations qui nous intéressent sont le
numéro d'immatriculation, la marque du véhicule et le nombre de fenêtres de celui-ci, qui
nous servira à calculer le montant d'une taxe.

1. Écrire une classe Voiture contenant un champ plaque de type Immatriculation, ainsi
que des champs marque et nombreDeFenetres repsectivement de type String et int.
2. Écrire les méthodes accesseurs de la classe puis une méthode toString() affichant la
marque, l'immatriculation et la taxe.
3. Écrire la méthode getMontantTaxe() qui calcule le montant de la taxe Alif selon la
formule 1000*nombreDeFenetres.

Exercice 3 - Généralisation à une classe Vehicule

On veut maintenant représenter 2 types de véhicules: les voitures et les motos. Les
informations d'immatriculation et de marque sont utiles pour les deux types. En revanche, les
motos n'ont pas de fenêtre et le montant de la taxe pour une moto est de :
vitesseMaxi*vitesseMaxi .

Enseignante : Mme I.JAOUANI Page 58


L2

1. En tenant compte des indications précédentes, proposer une architecture de classes


permettant de modéliser ces différents objets (penser à l'héritage).
2. Écrire les classes proposées. L'instruction vehicule.getMontantTaxe() doit retourner le
montant de la taxe correctement calculée, que vehicule représente une moto ou bien
une voiture.

Enseignante : Mme I.JAOUANI Page 59


L2

Chapitre V

Enseignante : Mme I.JAOUANI Page 60


L2

Chapitre 5 : Classes abstraites et interfaces

Vue d’ensemble

Cette leçon introduit les notions de classes abstraites et interfaces

Objectifs
A la fin de cette leçon, l’étudient sera capable :
 Introduire la notion de classes abstraite, les règles de définition et les intérêts pratiques
 Introduire le concept d’interfaces, leurs intérêts pratiques et leurs relations avec
l’héritage

Durée : 3h

Pré-requis :
 Algorithmique et structures de données 1
 Atelier de programmation 1
 Classes et objets
 Héritage

Enseignante : Mme I.JAOUANI Page 61


L2

1. Classes abstraites
Les classes abstraites sont des classes dont le seul but est de fournir des informations communes
aux sous classes. Elles peuvent contenir tout ce qu’une classe normale peut contenir (variables
et méthodes de classe, d’instance …).
Une classe abstraite comprend au moins une méthode abstraite. Elle est déclarée avec le mot
clé abstract.

Syntaxe :

abstract class NomClasse {… ........ }

Une classe abstraite est une classe qui n’est pas concrète (ayant toutes ses méthodes qui sont
implémentées). Elle ne peut pas être instanciée.
Une sous classe de la classe abstraite doit implémenter toutes les méthodes de la classe
abstraite.

Utilité :

 Une classe abstraite est utilisée généralement pour faire des dérivations. Les classes
dérivées qui sont complètement implémentées peuvent être instanciées.

Remarques :

 Les méthodes déclarées static, private et final ne peuvent pas être déclarées abstraites.
 Une classe déclarée final ne peut pas être abstraite.
 Les méthodes d’une classe abstraite doivent être publique.
Exemple :

Classe Figuregeom

Classe Cercle Classe Rectangle

Figure 4: Exemple de classe Abstraite

Enseignante : Mme I.JAOUANI Page 62


L2

La définition de la super classe « Figuregeom » :

public abstract class Figuregeom


{
public abstract double surface ();

public abstract double perimetre();


}

La définition de la sous-classe « Cercle » :

public class Cercle extends Figuregeom


{
protected double r;
public Cercle (double r)
{
this.r = r;
}
public double RetourRayon()
1 {
return r;
}
public double surface ()
{
return (Math.PI * r * r);
}
public double perimetre ()
{
return (2 * Math.PI * r);
}

}// fin de la classe Cercle

Enseignante : Mme I.JAOUANI Page 63


L2

La définition de la sous-classe « Rectangle » :

public class Rectangle extends Figuregeom


{
protected double l, L;
public Rectangle (double l, double L)
{
this.l = l;
this.l = L;
}
public double RectangleLong()
{
return L;

}
public double RectangleLarg()
{
return l;
}
public double surface ()
{
return (l * L);
}
public double perimetre()
{
return (l + L)* 2;
}
}// fin de la classe Rectangle

La définition de la classe « Test » :

Enseignante : Mme I.JAOUANI Page 64


L2
public class Test
{
public static void main(String[] args)
{
Figuregeom [] t = new Figuregeom [3];
// création d'un tableau de type figure geom
//mais pas une instance de la classe
t[0] = new Cercle(2.0);
t[1] = new Rectangle (1.5, 3.2);
t[2] = new Cercle(3.6);
double totalSurface = 0;
for (int i = 0; i < t.length; i++)
{
totalSurface = t[i].surface();
System.out.println ("Surface totale est : " +
totalSurface);
}
}

}// fin de la classe Test

2. Interfaces

Dans le cadre de Java, un type de données est une classe et un type de données abstrait est une
interface. Le mécanisme de l’interface est une généralisation de concept de classe abstraite.

2.1. Définition

Une interface est une classe qui ne comporte que des méthodes sans implémentation. On
trouve seulement les prototypes de ces fonctions (il faut mettre les noms des paramètres
formels). Une interface peut contenir des variables constantes de la forme : final int i = 10 ;
Au niveau de la syntaxe, on introduit une interface non plus avec le mot clé class mais avec le
mot clé interface.

Une définition d’interface possède 2 composants :

Enseignante : Mme I.JAOUANI Page 65


L2

 La déclaration de l’interface
 Le corps de l’interface

Syntaxe :
En-tête

interface Nom_Interface
{
Méthode 1 (liste d’arguments) ;
………..
Corps
Méthode 2 (liste d’arguments) ;
}

Une classe n’hérite pas d’une interface, mais elle l’implémente. On utilise le mot clé
implements.

Syntaxe :

class NomClasse implements Nom_Interface

{………..}

Une classe ne peut hériter que d’une seule classe (héritage simple), alors que l’on peut
implémenter plusieurs interfaces.

Syntaxe :

class NomClasse implements Nom_Interface1, Nom_Interface2,…

{………..}

Remarques :

 Une interface peut hériter d’une ou de plusieurs autres interfaces.


 Les constantes déclarées dans une interface sont implicitement public, static et final.
 Toutes les méthodes déclarées dans le corps d’une interface sont implicitement public et
abstract.

Enseignante : Mme I.JAOUANI Page 66


L2

 Les modificateurs private ou protected ne sont jamais utilisés dans une interface.
 L’interface est contenue dans un fichier à part.
 Le nom d’une interface commence par I.
 On peut avoir une classe sans méthodes mais elle implémente toutes les méthodes de
l’interface.

Exemples :

public interface I1
{
void m();
}

public abstract class C1


{
void g();
}

class C2 extends C1 implements I1


{
void m()
{
// le code de m ()
}
void g()
{
// le code de g()
}
}
public interface I2 extends I1
{
void n();
}

Enseignante : Mme I.JAOUANI Page 67


L2

abstract class C3 implements I2


{
void n()
{
//le code de n()
}
}

Class MyClass extends C2 implements I1 , I2

{………………}

2.2 Utilité des interfaces

 Une interface définie une sorte de cahier de charges concernant un certain comportement
(ensemble d'opérations).
 Chaque classe qui implémente une interface garantit à ses utilisateurs qu'elle est capable de
faire ce que l’interface spécifie via ses méthodes (assurer les opérations définies par
l'interface).

2.3 Règles d’implémentation d’une interface

 Par convention, la clause extends vient toujours avant la clause implements.


 Une classe qui implémente une interface doit définir toutes les méthodes de l’interface.
 Les interfaces doivent être spécifiées de manière complète dès le départ.

Enseignante : Mme I.JAOUANI Page 68


L2

3. Contrôle des acquis

On va considérer une classe « CompteurAbstrait » caractérisé par les attributs et les méthodes
suivants :
 Min : c’est la valeur minimale du compteur
 Courant : c’est la valeur courant du compteur
 RAZ : c’est la méthode qui permet de mettre à zéro le compteur
 1 constructeur
 Incrément : c’est la méthode abstraite qui permet d’incrémenter le compteur

Soit la classe « CompteurOrd » qui est une classe dérivée de la classe


« CompteurAbstrait » et qui permet la méthode abstrait Incrément de façon que le compteur
ne s’incrémente pas.
Soit la classe « CompteurCycl » qui est une classe dérivée de la classe
« CompteurAbstrait ». Un compteur cyclique possède en plus un attribut max qui indique la
valeur maximale du compteur et s’incrémente de façon cyclique c'est-à-dire il revient à la valeur
min s’il atteint la valeur max.
Travail Demandé :
Implémenter les 3 classes décrites et écrire une classe TestCompteur qui permet de déclarer 2
objets de type « CompteurAbstrait ». Faite l’instanciation de l’un comme compteur et l’autre
comme compteur cyclique.
Ajouter une boucle dans laquelle vous incrémenter simultanément vos compteurs et afficher à
chaque fois les valeurs courantes des compteurs.

Enseignante : Mme I.JAOUANI Page 69


L2

Chapitre VI

Enseignante : Mme I.JAOUANI Page 70


L2

Chapitre 6 : Le polymorphisme

Vue d’ensemble

Objectifs
A la fin de cette leçon, l’étudient sera capable :
 Comprendre le principe de polymorphisme à travers des exemples
 Comprendre la conversion des arguments en liaison avec le polymorphisme
 Comprendre la conversion explicite des références en rapport avec le polymorphisme

Durée : 3 h

Pré-requis :
 Algorithmique et structures de données 1
 Atelier de programmation 1
 Classes et objets
 Héritage
 Classes Abstraites et interfaces

Enseignante : Mme I.JAOUANI Page 71


L2

1. Introduction
Il s’agit d’un concept extrêmement puissant en P.O.O., qui complète l’héritage. On peut
caractériser le polymorphisme en disant qu’il permet de manipuler des objets sans en connaître
(tout à fait) le type.
Par exemple, on pourra construire un tableau d’objets les uns étant de type Point, les autres
étant de type Pointcol (dérivé de Point) et appeler la méthode affiche pour chacun des objets
du tableau. Chaque objet réagira en fonction de son propre type.

2. Les bases du polymorphisme


Considérons cette situation dans laquelle les classes Point et Pointcol sont censées
disposer chacune d’une méthode affiche.
class Point
{
public Point (int x, int y) { ...... }
public void affiche() { ...... }
}

class Pointcol extends Point


{
public Pointcol (int x, int y, byte couleur)
public void affiche() { ...... }
}
Avec ces instructions :
Point p;
p=new Point(3,5);
On aboutit tout naturellement à cette situation :

Mais il se trouve que Java autorise ce genre d’affectation (p étant toujours de type Point)
p=new Pointcol(4,8,(byte)2); // p de type Point contient la référence
// à un objet de type Pointcol
La situation correspondante est la suivante :

Enseignante : Mme I.JAOUANI Page 72


L2

D’une manière générale, Java permet d’affecter à une variable objet non seulement la référence
à un objet du type correspondant, mais aussi une référence à un objet d’un type dérivé.
On peut dire qu’on est en présence d’une conversion implicite (légale) d’une référence à un
type classe T en une référence à un type ascendant de T; on parle aussi de compatibilité par
affectation entre un type classe et un type ascendant.
Considérons maintenant ces instructions :
Point p=new Point(3,5);
p.affiche(); // appelle la méthode affiche de la classe Point

p=new Pointcol(4,8,2);
p.affiche(); // appelle la méthode affiche de la classe Pointcol

Dans la dernière instruction, la variable p est de type Point, alors que l’objet référencé par p
est de type Pointcol. L’instruction p.affiche()appelle alors la méthode affiche de
la classe Pointcol.
Autrement dit, elle se fonde, non pas sur le type de la variable p, mais sur le type effectif de
l’objet référencé par p au moment de l’appel.
Ce choix d’une méthode au moment de l’exécution (et non plus de la compilation) porte
généralement le nom de ligature dynamique (ou encore de liaison dynamique).

En résumé, le polymorphisme en Java se traduit par :


- la compatibilité par affectation entre un type classe et un type ascendant,
- la ligature dynamique des méthodes.

Le polymorphisme permet d’obtenir un comportement adapté à chaque type d’objet, sans


avoir besoin de tester sa nature de quelque façon que ce soit.

Enseignante : Mme I.JAOUANI Page 73


L2

Exemple 1
Voici un premier exemple intégrant les situations exposées ci-dessus dans un programme
complet :

class Point
{
private int x, y ;
public Point (int x, int y)
{
this.x = x ; this.y = y ;
}
public void deplace (int dx, int dy)
{
x += dx ; y += dy ;
}
public void affiche ()
{
System.out.println ("Je suis en " + x + " " + y) ;
}

class Pointcol extends Point


{
private byte couleur;
public Pointcol(int x, int y, byte couleur)
{
super (x, y); // obligatoirement comme première instruction
this.couleur=couleur;
}
public void affiche()
{
super.affiche();
System.out.println(" et ma couleur est : " +couleur);

Enseignante : Mme I.JAOUANI Page 74


L2

}
}
public class Poly
{
public static void main (String args[])
{
Point p=new Point(3,5);
p.affiche(); // appelle affiche de Point
Pointcol pc=new Pointcol(4,8,(byte)2);
p=pc ; //p de type Point, référence un objet de type Pointcol
p.affiche();//on appelle affiche de Pointcol
p=new Point(5,7); //p référence à nouveau un objet de type Point
p.affiche(); // on appelle affiche de Point
}
}

Exemple 2 :
Créer un tableau "hétérogène" d’objets, c’est-à-dire dans lequel les éléments peuvent être de
type différent.
public class TabHeter
{
public static void main(String args[])
{
Point tabPts[]=new Point[4];
tabPts[0]=new Point(0,2);
tabPts[1]=new Pointcol (1, 5, (byte)3);
tabPts[2]=new Pointcol (2, 8, (byte)9);
tabPts[3]=new Point (1, 2);
for (int i=0;i<tabPts.length;i++)
tabPts[i].affiche();
}
}

Enseignante : Mme I.JAOUANI Page 75


L2

3. Généralisation à plusieurs classes


On vient d’exposer les fondements du polymorphisme en ne considérant que deux classes.
Mais il va de soi qu’ils se généralisent à une hiérarchie quelconque.
Considérons par exemple la hiérarchie de classes suivante, dans laquelle seules les classes
marquées d’un astérisque définissent ou redéfinissent une méthode f :

Avec ces déclarations : A a; B b; C c; D d; E e; F f;

Les affectations suivantes sont légales : a=b; a=c;a=d;a=e;a=f; b=d; b=e; c=f;

En revanche, celles-ci ne le sont pas :


b=a; // erreur : A ne descend pas de B
d=c; // erreur : C ne descend pas de D
c=d; // erreur : D ne descend pas de C
Voici quelques exemples précisant la méthode f appelée, selon la nature de l’objet
effectivement référencé par a (de type A) :
a référence un objet de type A : méthode f de A
a référence un objet de type B : méthode f de A
a référence un objet de type C : méthode f de C
a référence un objet de type D : méthode f de D
a référence un objet de type E : méthode f de A
a référence un objet de type F : méthode f de C.

Enseignante : Mme I.JAOUANI Page 76


L2

4. Redéfinition et surdéfinition
Par essence, le polymorphisme se fonde sur la redéfinition des méthodes. Mais il est aussi
possible de surdéfinir une méthode.
Exemple :
class A
{
public void f(float x) { ...... }
.....
}

class B extends A
{
public void f(float x) { ..... } // redéfinition de f de A
public void f(int n) { ..... } // surdéfinition de f pour A et B
.....
}

A a=new A(. );
B b=new B(. );
int n;
a.f(n); // appelle f (float) de A (ce qui est logique)
b.f(n); // appelle f(int) de B comme on s’y attend
a=b; // a contient une référence sur un objet de type B
a.f(n); // appelle f(float) de B et non f(int)
Ainsi, bien que les instructions b.f(n) et a.f(n) appliquent toutes les deux une méthode
f à un objet de type B, elles n’appellent pas la même méthode.
Voyons plus précisément pourquoi.

En présence de l’appel a.f(n), le compilateur recherche la meilleure méthode (règles de


surdéfinition) parmi toutes les méthodes de la classe correspondant au type de a (ici A) ou ses
ascendantes. Ici, il s’agit de void f(float x) de A.

Enseignante : Mme I.JAOUANI Page 77


L2

À ce stade donc, la signature de la méthode et son type de retour sont entièrement figés. Lors
de l’exécution, on se fonde sur le type de l’objet référencé par a pour rechercher une méthode
ayant la signature et le type de retour voulus.
On aboutit alors à la méthode void f(float x) de B, et ce malgré la présence
(également dans B) d’une méthode qui serait mieux adaptée au type de l’argument effectif.

Ainsi, malgré son aspect ligature dynamique, le polymorphisme se fonde sur une signature
et un type de retour définis à la compilation (et qui ne seront donc pas remis en question lors
de l’exécution).

5. Les règles du polymorphisme en Java

Dans les situations usuelles, le polymorphisme est facile à comprendre et à exploiter.


Cependant, on a vu que l’abus des possibilités de surdéfinition des méthodes pouvait conduire
à des situations complexes. Alors on se propose de récapituler les différentes règles
rencontrées progressivement.
 Compatibilité. Il existe une conversion implicite d’une référence à un objet de classe
T en une référence à un objet d’une classe ascendante de T (elle peut intervenir aussi
bien dans les affectations que dans les arguments effectifs).
 Ligature dynamique. Dans un appel de la forme x.f(...) où x est supposé de
classe T, le choix de f est déterminé ainsi :
- à la compilation : on détermine dans la classe T ou ses ascendantes la signature
de la meilleure méthode f convenant à l’appel, ce qui définit du même coup le
type de la valeur de retour.
- à l’exécution : on recherche la méthode f de signature et de type de retour voulus
à partir de la classe correspondant au type effectif de l’objet référencé par x (il est
obligatoirement de type T ou descendant) ; si cette classe ne comporte pas de
méthode appropriée, on remonte dans la hiérarchie jusqu’à ce qu’on en trouve une
(au pire, on remontera jusqu’à T).

Enseignante : Mme I.JAOUANI Page 78


L2

6. Contrôle des acquis

Exercice 1
Quels résultats fournit le programme suivant ?
class A
{
public void affiche() { System.out.print("Je suis un A "); }
}

class B extends A {}

class C extends A
{
public void affiche() { System.out.print("Je suis un C "); }
}
class D extends C
{
public void affiche() { System.out.print("Je suis un D "); }
}

class E extends B {}
class F extends C {}

public class Poly


{
public static void main (String arg[])
{
A a=new A(); a.affiche(); System.out.println();
B b=new B(); b.affiche();
a=b; a.affiche(); System.out.println();
C c=new C(); c.affiche() ;
a=c; a.affiche() ; System.out.println();
D d=new D() ; d.affiche() ;
a=d; a.affiche();
c=d; c.affiche(); System.out.println();
E e=new E(); e.affiche();
a=e; a.affiche();
b=e ; b.affiche(); System.out.println();
F f=new F(); f.affiche();

Enseignante : Mme I.JAOUANI Page 79


L2
a = f; a.affiche();
c = f; c.affiche();
}
}

Certaines possibilités d’affectation entre objets des types classes A, B, C, D, E et F ne figurent pas dans le
programme ci-dessus. Pourquoi ?

Exercice 2
Quels résultats fournit le programme suivant ?
class A
{
public void f(double x)
{
System.out.print("A.f(double=" + x +") ");
}
}
class B extends A {}

class C extends A
{
public void f(long q)
{
System.out.print("C.f(long=" + q + ") ");
}
}

class D extends C
{
public void f(int n)
{
System.out.print("D.f(int=" + n + ") ");
}
}

class F extends C
{
public void f(float x)
{
System.out.print("F.f(float=" + x + ") ");

Enseignante : Mme I.JAOUANI Page 80


L2
}

public void f(int n)


{
System.out.print("F.f(int=" + n + ") ");
}
}

public class PolySur


{
public static void main(String arg[])
{
byte bb=1; short p=2; int n=3; long q=4;
float x=5.f; double y=6. ;

System.out.println("** A ** ");
A a=new A(); a.f(bb); a.f(x); System.out.println();

System.out.println("** B ** ");
B b=new B(); b.f(bb); b.f(x); System.out.println();
a=b; a.f(bb);a.f(x);System.out.println() ;

System.out.println("** C ** ");
C c=new C(); c.f(bb); c.f(q); c.f(x); System.out.println();
a=c; a.f(bb); a.f(q); a.f(x); System.out.println();

System.out.println("** D ** ");
D d=new D(); d.f(bb); c.f(q); c.f(y); System.out.println();
a=c; a.f(bb); a.f(q); a.f(y); System.out.println();

System.out.println("** F ** ");
F f=new F(); f.f(bb); f.f(n); f.f(x); f.f(y); System.out.println();
a=f; a.f(bb);a.f(n); a.f(x); a.f(y); System.out.println();
c = f; c.f(bb); c.f(n); c.f(x); c.f(y);
}
}

Exercice 3
Soient les classes Point et PointNom ainsi définies :

class Point

Enseignante : Mme I.JAOUANI Page 81


L2
{
public Point(int x, int y)
{
this.x=x; this.y=y;
}

public static boolean identiques(Point a, Point b)


{
return ((a.x==b.x) && (a.y==b.y));
}

public boolean identique(Point a)


{
return ( (a.x==x) && (a.y==y));
}

private int x, y ;
}

class PointNom extends Point


{
PointNom(int x, int y, char nom)
{
super(x, y); this.nom=nom;
}

private char nom;


}
1) Quels résultats fournit ce programme ? Expliciter les conversions mises en jeu et les règles
utilisées pour traiter les différents appels de méthodes :
public class LimPoly
{
public static void main(String args[])
{
Point p=new Point(2,4);
PointNom pn1=new PointNom(2, 4, 'A');
PointNom pn2=new PointNom(2, 4, 'B');
System.out.println(pn1.identique(pn2));
System.out.println(p.identique(pn1));
System.out.println(pn1.identique(p));

Enseignante : Mme I.JAOUANI Page 82


L2
System.out.println(Point.identiques(pn1, pn2));
}
}

2) Doter la classe PointNom d’une méthode statique identiques et d’une méthode


identique fournissant toutes les deux la valeur true lorsque les deux points concernés
ont à la fois mêmes coordonnées et même nom.
Quels résultats fournira alors le programme précédent ? Quelles seront les conversions mises
en jeu et les règles utilisées ?

Enseignante : Mme I.JAOUANI Page 83


L2

Chapitre 7

Enseignante : Mme I.JAOUANI Page 84


L2

Chapitre 7 : Gestion des exceptions

Vue d’ensemble

Le but de cette dernière leçon est d’introduire la notion d’exception en langage java

Objectifs :
 Introduire la notion d’exception, les règles d’utilisation et de définition des
exceptions
 Distinguer entre les exceptions prédéfinies et les exceptions définies par les
utilisateurs

Durée : 1.5 h

Pré-requis :
 Algorithmique et structures de données 1
 Atelier de programmation 1
 Classes et objets

Enseignante : Mme I.JAOUANI Page 85


L2

1. Introduction

Les exceptions représentent le mécanisme de gestion des erreurs intégré au langage


Java. Il se compose d'objets représentant les erreurs et d'un ensemble de trois mots clés qui
permettent de détecter et de traiter ces erreurs ( try, catch et finally ) et de les lever ou les
propager (throw et throws).

Lors de la détection d'une erreur, un objet qui hérite de la classe Exception est créé (on dit
qu'une exception est levée) et propagé à travers la pile d'exécution jusqu'à ce qu'il soit traité.

Ces mécanismes permettent de renforcer la sécurité du code Java.

Exemple d’exception (division par 0): une exception levée à l'exécution non capturée

public class TestException {


public static void main(String[] args) {
int i = 3;
int j = 0;
System.out.println("résultat = " + (i / j));
}
}

Résultat :

C:>java TestException
Exception in thread "main" java.lang.ArithmeticException: /
by zero
at tests.TestException.main(TestException.java:23)

Si dans un bloc de code, on fait appel à une méthode qui peut potentiellement générer
une exception, on doit soit essayer de la récupérer avec try/catch, soit ajouter le mot clé
throws dans la déclaration du bloc. Si on ne le fait pas, il y a une erreur à la compilation. Les

Enseignante : Mme I.JAOUANI Page 86


L2

erreurs et exceptions du paquetage java.lang échappent à cette contrainte. Throws permet de


déléguer la responsabilité des erreurs vers la méthode appelante.

Ce procédé présente un inconvénient : de nombreuses méthodes des packages java indiquent


dans leur déclaration qu'elles peuvent lever une exception. Cependant ceci garantie que
certaines exceptions critiques seront prises explicitement en compte par le programmeur.

2. Les mots clés try, catch et finally

* Le bloc try rassemble les appels de méthodes susceptibles de produire des erreurs ou des
exceptions. L'instruction try est suivie d'instructions entre des accolades.

Exemple :

try {
operation_risquée1;
opération_risquée2;
}
catch (ExceptionInteressante e)
{
traitements
} catch (ExceptionParticulière e) {
traitements
} catch (Exception e) {
traitements
} finally {
traitement_pour_terminer_proprement;
}

Si un événement indésirable survient dans le bloc try, la partie éventuellement non


exécutée de ce bloc est abandonnée et le premier bloc catch est traité. Si catch est défini pour
capturer l'exception issue du bloc try alors elle est traitée en exécutant le code associé au bloc.
Si le bloc catch est vide (aucune instruction entre les accolades) alors l'exception capturée est

Enseignante : Mme I.JAOUANI Page 87


T.I.2

ignorée. Une telle utilisation de l'instruction try/catch n'est pas une bonne pratique : il est
préférable de toujours apporter un traitement adapté lors de la capture d'une exception.

S'il y a plusieurs types d'erreurs et d'exceptions à intercepter, il faut définir autant de bloc
catch que de type d'événement. Par type d'exception, il faut comprendre « qui est du type de la
classe de l'exception ou d'une de ses sous classes ». Ainsi dans l'ordre séquentiel des clauses
catch, un type d'exception de ne doit pas venir après un type d'une exception d'une super
classe. Il faut faire attention à l'ordre des clauses catch pour traiter en premier les exceptions
les plus précises (sous classes) avant les exceptions plus générales. Un message d'erreur est
émis par le compilateur dans le cas contraire.

Exemple : erreur à la compilation car Exception est traité en premier alors que
ArithmeticException est une sous classe de Exception

public class TestException {


public static void main(String[] args) {
int i = 3;
int j = 0;
try {
System.out.println("résultat = " + (i / j));
}
catch (Exception e) {
}
catch (ArithmeticException e) {
}
}
}

Résultat :

C:\tests>javac TestException.java
TestException.java:11: catch not reached.
catch (ArithmeticException e) {
^
1 error

Enseignante : Melle Imen JAOUANI Page 88


L2

Si l'exception générée est une instance de la classe déclarée dans la clause catch ou
d'une classe dérivée, alors on exécute le bloc associé. Si l'exception n'est pas traitée par un
bloc catch, elle sera transmise au bloc de niveau supérieur. Si l'on ne se trouve pas dans un
autre bloc try, on quitte la méthode en cours, qui régénère à son tour une exception dans la
méthode appelante.

L'exécution totale du bloc try et d'un bloc d'une clause catch sont mutuellement
exclusives : si une exception est levée, l'exécution du bloc try est arrêtée et si elle existe, la
clause catch adéquate est exécutée.

*La clause finally définit un bloc qui sera toujours exécuté, qu'une exception soit levée ou
non. Ce bloc est facultatif. Il est aussi exécuté si dans le bloc try il y a une instruction break
ou continue.

3. La classe Throwable

Cette classe descend directement de la classe Object : c'est la classe de base pour le
traitement des erreurs. Cette classe possède deux constructeurs :

Méthode Rôle

Throwable()

La chaîne en paramètre permet de définir un message


Throwable(String) qui décrit l'exception et qui pourra être consultée dans
un bloc catch.

Tableau 5 : Constructeurs de la classe Throwable

Les principales méthodes de la classe Throwable sont :

Méthodes Rôle

String getMessage( ) lecture du message

affiche l'exception et l'état de la pile d'exécution au


void printStackTrace( )
moment de son appel

Enseignante : Mme JAOUANI Page 89


L2

void printStackTrace(PrintStream s) Idem mais envoie le résultat dans un flux

Tableau 6 : Méthodes de la classe Throwable

Exemple:

public class TestException {


public static void main(String[] args) {
int i = 3;
int j = 0;
try {
System.out.println("résultat = " + (i / j));
}
catch (ArithmeticException e) {
System.out.println("getmessage");
System.out.println(e.getMessage());
System.out.println(" ");
System.out.println("toString");
System.out.println(e.toString());
System.out.println(" ");
System.out.println("printStackTrace");
e.printStackTrace();
}
}
}

Résultat :

C:>java TestException
getmessage
/ by zero
toString
java.lang.ArithmeticException: / by zero

Enseignante : Mme JAOUANI Page 90


L2

printStackTrace
java.lang.ArithmeticException: / by zero
at tests.TestException.main(TestException.java:24)

4. Les classes Exception, RunTimeException et Error

Ces trois classes descendent de Throwable : en fait, toutes les exceptions dérivent de la
classe Throwable.

Figure 5 : Hiérarchie des classes d’exception java

La classe Error représente une erreur grave intervenue dans la machine virtuelle Java
ou dans un sous système Java. L'application Java s'arrête instantanément dès l'apparition d'une
exception de la classe Error.

La classe Exception représente des erreurs moins graves. Les exceptions héritant de
classe RuntimeException n'ont pas besoin d'être détectées impérativement par des blocs
try/catch.

5. Les exceptions personnalisées

Pour générer une exception, il suffit d'utiliser le mot clé throw, suivi d'un objet dont la
classe dérive de Throwable. Si l'on veut générer une exception dans une méthode avec
throw, il faut l'indiquer dans la déclaration de la méthode, en utilisant le mot clé throws.

Enseignante : Mme JAOUANI Page 91


L2

En cas de nécessité, on peut créer ses propres exceptions. Elles descendent des classes
Exception ou RunTimeException mais pas de la classe Error. Il est préférable (par
convention) d'inclure le mot « Exception » dans le nom de la nouvelle classe.

Exemple :

public class SaisieErroneeException extends Exception {


public SaisieErroneeException() {
super();
}
public SaisieErroneeException(String s) {
super(s);
}
}

public class TestSaisieErroneeException {


public static void controle(String chaine) throws
SaisieErroneeException {
if (chaine.equals("") == true)
throw new SaisieErroneeException("Saisie erronee : chaine vide");
}
public static void main(java.lang.String[] args) {
String chaine1 = "bonjour";
String chaine2 = "";
try {
controle(chaine1);
}
catch (SaisieErroneeException e) {
System.out.println("Chaine1 saisie erronee");
};
try {
controle(chaine2);
}

Enseignante : Mme JAOUANI Page 92


L2

catch (SaisieErroneeException e) {
System.out.println("Chaine2 saisie erronee");
};
}
}

Les méthodes pouvant lever des exceptions doivent inclure une clause throws
nom_exception dans leur en tête. L'objectif est double : avoir une valeur documentaire et
préciser au compilateur que cette méthode pourra lever cette exception et que toute méthode
qui l'appelle devra prendre en compte cette exception (traitement ou propagation).

Si la méthode appelante ne traite pas l'erreur ou ne la propage pas, le compilateur génère


l'exception nom_exception must be caught or it must be déclared in the thows clause of this
méthode.

Java n'oblige la déclaration des exceptions dans l'en tête de la méthode que pour les
exceptions dites contrôlées (checked). Les exceptions non contrôlées (unchecked) peuvent
être capturées mais n'ont pas à être déclarées. Les exceptions et erreurs qui héritent de
RunTimeException et de Error sont non contrôlées. Toutes les autres exceptions sont
contrôlées.

7. L'utilisation des exceptions

Il est préférable d'utiliser les exceptions fournies par Java lorsque qu'une de ces exceptions
répond au besoin plutôt que de définir sa propre exception.

Il existe trois types d'exceptions :

 Error : ces exceptions concernent des problèmes liés à l'environnement. Elles héritent
de la classe Error (exemple : OutOfMemoryError)
 RuntimeException : ces exceptions concernent des erreurs de programmation qui
peuvent survenir à de no
 mbreux endroits dans le code (exemple : NullPointerException). Elles héritent de la
classe RuntimeException

Enseignante : Mme JAOUANI Page 93


L2

 Checked exception : ces exceptions doivent être traitées ou propagées. Toutes les
exceptions qui n'appartiennent pas aux catégories précédentes sont de ce type

Les exceptions de type Error et RuntimeException sont dites unchecked exceptions car les
méthodes n'ont pas d'obligation à les traiter ou déclarer leur propagation explicitement. Ceci
se justifie par le fait que leur levée n'est pas facilement prédictible.

Il n'est pas recommandé de créer ces propres exceptions en dérivant d'une exception de type
unchecked (classe de type RuntimeException). Même si cela peut sembler plus facile
puisqu'il n'est pas obligatoire de déclarer leur propagation, cela peut engendrer certaines
difficultés, notamment :

 oublier de traiter cette exception


 ne pas savoir que cette exception peut être levé par une méthode.

Cependant, l'utilisation d'exceptions de type unchecked se répand de plus en plus notamment


depuis la diffusion de la plate-forme.

7. Contrôle des acquis


Exercice
Réaliser une classe EntNat permettant de manipuler des entiers naturels (positifs ou nuls).
Pour l’instant, cette classe disposera simplement :
• d’un constructeur à un argument de type int qui générera une exception de type
ErrConst (type classe à définir) lorsque la valeur reçue ne conviendra pas,
• d’une méthode getN fournissant sous forme d’un int, la valeur encapsulée dans un
objet de type EntNat.
Écrire un petit programme d’utilisation qui traite l’exception ErrConst en affichant un
message et en interrompant l’exécution.

Enseignante : Mme JAOUANI Page 94


L2

Proposition d’examens
« Énoncés/Corrections »

Enseignante : Mme JAOUANI Page 95


L2

Examen : POO (2009/2010 – Semestre 1)

*Questions de cours (2 points)


Répondez en une ou deux lignes maximum aux questions suivantes:

1 Que signifie le mot clé static en Java ? (1 point)

2. Que signifie le mot clé protected en Java ? (1 point)

Exercice (18 points)


On souhaite gérer une bibliothèque pouvant contenir différents types de documents. Soit la
classe abstraite Document caractérisée par :
 Titre, ID, NB_Page : Attributs entiers privées.
 Un constructeur qui permet d’initialiser les différents attributs de la classe Document.
 Des méthodes ; getTitre, SetTitre, getID, setID, getNB_Page, setNB_Page.
 Une méthode abstraite void Edition() qui affiche à l’écran le type de document et ses
caractéristiques.
 Une méthode abstraite getType qui retourne le type de document.

1. Implémenter la classe abstraite Document.

La bibliothèque contient différents types de documents :

Enseignante : Mme JAOUANI Page 96


L2

Des articles : Ce sont des Documents possédant une caractéristique complémentaire : le nom
d’auteur.
Des livres : Ce sont des articles possédant une caractéristique complémentaire : le nom de
l’éditeur.
Des périodiques : Ce sont des documents possédant une caractéristique complémentaire : le
nombre d’édition.
2. Implémenter les classes : Article, Livre et Périodique.

Chaque document est inséré lors de sa création dans une bibliothèque. C’est pourquoi on doit
aussi implémenter la classe Bibliothèque caractérisée par les attributs et les méthodes suivantes
:
Listdoc : c’est un tableau de documents.
Nombre de documents : c’est un attribut qui indique le nombre de documents ajoutés dans la
bibliothèque.
Un constructeur qui permet d’initialiser une bibliothèque en indiquant sa capacité maximale.
void ajout_doc (Document d) : c’est une méthode qui permet d’ajouter un document dans la
bibliothèque en respectant l’ordre des numéros d’identification.
void supprim_doc (int num) : c’est une méthode qui supprime un document de la
bibliothèque à partir de son numéro d’identification.
void Inventaire_doc() : c’est une méthode qui édite la liste de tous les documents avec leurs
types.
int getNombre_document() : retourne le nombre de documents.
3. Implémenter la classe Bibliothèque.
4. Ecrire la classe TestBibliothèque qui permet de tester les classes déjà construites : instancier
la classe bibliothèque, ajouter différents types de documents, faire l’inventaire et supprimer le
premier document ajouté.

Enseignante : Mme JAOUANI Page 97


L2

Correction Examen : POO (2009/2010 – Semestre 1)


Abstract class Document {//total barème 5 points

Private int Titre, ID, NB_P ; //0.5

Document ( int Titre, int ID, int NB_P) //0.5


{
This.Titre = Titre ;
This.ID = ID ;
This.NB_P = NB_P;
}
Int getTitre () //0.5
{
Return (Titre) ;
}
Int getID()//0.5
{
return (ID) ;
}
Int getNB_P()//0.5
{
Return(NB_P) ;
}
Void setTitre(int leTitre)//0.5
{

Titre = leTitre ;

Enseignante : Mme JAOUANI Page 98


L2
}
Void setID(int leID)//0.5
{
ID = leID ;
}
Void setTitre(int leNB_P)//0.5
{

NB_P = leNB_P ;
}
Abstract void Edition() ; // 0.5
Abstract String getType() ; //0.5

}//fin class Document

//total 2 points
Class Article extends Document //0.25
{
String NomH; //0.25
Article ( String Titre, int ID, int NB_P, String NomH)//0.5
{
Super(Titre,ID,NB_P) ;
This.NomH = NomH ;
}
String gettype ()//0.5
{
Return (“Article”);
}
Void Edition()//0.5
{
System.out.println (“le titre de l’article est “ + titre + “ identifier par » + ID + « le total des
pages est » + NB_P) ;
}
}//fin class Article
//total bareme 2 points
Class Livre extends Articles {//0.25

String NomE;//0.25
Livre (String Titre, int ID, int NB_P, String NomH, String NomE)//0.5
{

Enseignante : Mme JAOUANI Page 99


L2
Super (Titre, ID, NB_P, NomH);
This.NomE = NomE ;
}
String gettype ()//0.5
{
Return (“Livre”);
}
Void Edition()//0.5
{
System.out.println (“le titre du Livre est “ + titre + “ identifier par » + ID + « le total des pages
est » + NB_P+ « le nom de l’éditeur est » + NomE) ;
}
}//fin class Article
//total 2 points
Class Periodique extends Document {//0.25

Int NBE ;//0.25


Livre (String Titre, int ID, int NB_P, int NBE)//0.5
{
Super (Titre, ID, NB_P);
This.NBE = NBE ;
}
String gettype ()//0.5
{
Return (“Periodique”);
}
Void Edition()//0.5
{
System.out.println (“le titre du Périodique est “ + titre + “ identifier par » + ID + « le total des
pages est » + NB_P+ « le nombre d’édition est » + NBE) ;
}
}
//total 4.5 points
Class Bibliotheque {
//0.5
Document listdoc[] ;
Int NbDoc ;
Bibliotheque (int cmax)//0.5
{
Listdoc = new Document[cmax] ;

Enseignante : Mme JAOUANI Page 100


L2
NbDoc = 0 ;
}
void ajout_doc (Document d) //1 point
{
Listdoc [d.ID] = d ;
NbDoc ++ ;
}

void supprim_doc (int num) //1 point


{
For(int i = num ; i < NbDoc ; i++)
{
Listdoc[i] = listdoc[i+1];
}
NbDoc -- ;

}
void Inventaire_doc() //1point
{
For(int i = num ; i < NbDoc ; i++)
{
Listdoc[i].Edition();
}

}
int getNombre_document() //0.5
{
Return NbDoc ;

}
}//fin class Bibliotheque
//total 2.5 points
Class TestBibliotheque
{

Public static void main (String args[])


{
Bibliotheque BIB= new Bibliotheque(10);//0.5
Document d1= new Document(“POO”,0,200);//0.5
Document d2= new Document(“base de données”,1,100);

Enseignante : Mme JAOUANI Page 101


L2
BIB.ajout_doc (d1);//0.5
BIB.ajout_doc (d1);
BIB.Inventaire_doc ();//0.5
BIB.supprim_doc (0) ;//0.5
}
}//fin class TestBibliotheque

Enseignante : Mme JAOUANI Page 102


L2

Examen : POO (2010/2011 – Semestre 1)


Questions de cours : (5 Points, 15 min)

1/ Avec quel mot clé peut-on accéder aux méthodes d'une classe mère lorsque nous créons
une classe héritée ?
a- Super.
b- Hyper.
c- Ultra.
2/ Dans quel cas doit-on utiliser une classe abstraite ?
a- Pour faire une classe mère.
b- Pour faire une classe mère qui ne doit pas être instanciée.
c- Pour faire une classe héritée.
3/ Que va afficher ce code ?
public class A{
public A(){ System.out.println("1"); }
}
public class B extends A{}
public class Test {
public static void main(String[] args){B b = new B();}
}

Enseignante : Mme JAOUANI Page 103


L2

a- Rien.
b- 1.
c- Erreur de compilation.
4/ Peut-on instancier une interface ?
a- Oui
b- Non
c- Je ne sais pas.

5/ Que signifie le mot clé static en Java ?


Exercice 1 : (10 points, 1 h15)

Une société vend des articles de papeterie, parmi lesquels, on trouve ce qui suit :
 des stylos décrits par :
1. une référence
2. un descriptif
3. une marque
4. un prix unitaire
5. une couleur
 des ramettes de papier décrites par
1.une référence
2.un descriptif
3.une marque
4.un prix unitaire
5.le grammage du papier (par exemple, 80 g/m²)

Travail demandé :

1. Écrire une classe « Article », sachant qu’un article est caractérisé par :
 un attribut référence de type entier
 un attribut descriptif de type chaîne de caractères
 un attribut marque de type chaîne de caractères
 un attribut prix unitaire de type double
 un constructeur qui permet d’initialiser les variables d’instance de la classe Article.

Enseignante : Mme JAOUANI Page 104


L2

 une méthode getPrix() qui retourne le prix unitaire de l'article.


 une méthode publique toString() qui retourne une chaîne de caractères contenant les
caractéristiques d’un article.
2. Écrire une classe « Stylo » qui hérite de la classe « Article », implémenter le constructeur
qui permet d’initialiser les variables d’instance de la classe Stylo et redéfinir la méthode
toString() (la couleur du stylo est de type entier).
3. Écrire une classe « RamettePapier » qui hérite de la classe «Article», implémenter le
constructeur qui permet d’initialiser les variables d’instance de la classe RamettePapier et
redéfinir la méthode toString() (le grammage du stylo est de type entier).
4. Implémenter une interface « IFacturable » qui possède la méthode :
public double calculerFacture()

5. Écrire une classe « Lot » qui contient un tableau d’objets « Article », et un attribut
nbArticles. La classe « Lot » implémente l’interface «Facturable» et comporte les
méthodes ci-dessous :

 Un constructeur qui permet d’initialiser le nombre d’articles.


 Une méthode publique getArticle(int i) qui retourne l'article d'indice i.
 public boolean ajouterArticle(Article a, int indice) : permet d’ajouter un article au
tableau d’articles et retourne true si l’opération d’ajout est effectuée avec succès
sinon false.
 public boolean supprimerArticle(Article a, int indice) : permet de supprimer un
article du tableau d’articles et retourne true si l’opération de suppression est
effectuée avec succès sinon false.
 public double calculerFacture() : permet de calculer la facture de tous les articles (
somme des prix des 10 articles) et de la retourner.

6. Écrire une classe de test « TestLot » qui permet de : (voir sortie console)

 créer un objet Lot A comportant 7 Stylo et 3 Ramette (pour ajouter un article, utiliser
l’appel à la méthode ajouterArticle …)
 afficher la description de chaque article,
 calculer puis afficher la facture du lot,

Enseignante : Mme JAOUANI Page 105


L2

 supprimer un article quelconque , recalculer et réafficher le prix du lot.

Sortie console :
article : ref:1 desc:stylo marq:bic pu:1.0 coul:5
article : ref:1 desc:stylo marq:bic pu:1.0 coul:5
article : ref:1 desc:stylo marq:bic pu:1.0 coul:5
article : ref:1 desc:stylo marq:bic pu:1.0 coul:5
article : ref:1 desc:stylo marq:bic pu:1.0 coul:5
article : ref:1 desc:stylo marq:bic pu:1.0 coul:5
article : ref:1 desc:stylo marq:bic pu:1.0 coul:5
article : ref:2 desc:Rame Papier marq:Paperus pu:6.0 grammage:3
article : ref:2 desc:Rame Papier marq:Paperus pu:6.0 grammage:3
article : ref:2 desc:Rame Papier marq:Paperus pu:6.0 grammage:3
la facture est de : 25.0 dinars
la facture est de : 19.0 dinars

Exercice 2 : (5 points, 30 min)


Soient le diagramme de classes ci-dessous :

Enseignante : Mme JAOUANI Page 106


L2

Les classes MedecinDeFamille et Chirurgien héritent de la classe Medecin.


1. Implémenter les trois classes Medecin, MedecinDeFamille et Chirurgien tels qu’elles sont
décrites dans le diagramme décrit ci-dessus (nbFamilles représente le nombre de famille
affectés au médecin de famille)
2. Ecrire une classe de Test nommée TestMedecin qui permet de Créer trois objets des classes
Medecin, MedecinDeFamille et Chirurgien et afficher pour chaque objet la description de
chacun.

Enseignante : Mme JAOUANI Page 107


L2

Correction Examen : POO (2010/2011 – Semestre 1)


Questions de cours : (5 Points, 15 min )

1/ Avec quel mot clé peut-on accéder aux méthodes d'une classe mère lorsque nous créons une classe
fille ? (1 pt)
d- Super.
e- Hyper.
f- Ultra.
2/ Créer une classe abstraite nous permet de ? (1 pt)
d- Créer une classe mère.
e- Créer une classe qui n’est pas directement instanciable.
f- Créer une classe fille.
3/ Que va afficher ce code ? (1 pt)

public class A{
public A(){ System.out.println("1"); }
}
public class B extends A{}
public class Test {
public static void main(String[] args){B b = new B();}
}

d- Rien.
e- 1.

Enseignante : Mme JAOUANI Page 108


L2
f- Erreur de compilation.
4/ Peut-on instancier une interface ? (1 pt)

d- Oui
e- Non
f- Je ne sais pas.

5/ Quand est-ce qu’on utilise le mot clé static pour une méthode en Java ? (1 pt)
Une méthode précédée par le mot clé « static » est dite statique (méthode de classe), cette
dernière peut être appelée même sans avoir instancié la classe. Une méthode statique ne peut
accéder qu'à des attributs et méthodes statiques.

Exercice 1 : (10 points, 1 h15)


7. package com.poo.exam;

public class Article {

public int ref;


public String description;
public String marque;
public double prix;

public Article(int pRef, String pDescription, String pMarque, double


pPrix) {
ref = pRef;
description = pDescription;
marque = pMarque;
prix = pPrix;
}

public double getPrix() {


return this.prix;
}

@Override
public String toString() {
return "description=" + description + ", marque=" + marque
+ ", prix=" + prix + ", reference=" + ref;

Enseignante : Mme JAOUANI Page 109


L2
}
}

package com.poo.exam;

public class Stylo extends Article {

public int couleur;

public Stylo(int pRef, String pDescription, String pMarque, double


pPrix,int pCouleur) {
super(pRef, pDescription, pMarque, pPrix);
couleur = pCouleur;
}

public String toString(){


return super.toString() + ", couleur= "+this.couleur;
}
}

package com.poo.exam;

public class RamettePapier extends Article {

public int grammage;

public RamettePapier(int pRef, String pDescription, String pMarque,


double pPrix, int pGrammage) {
super(pRef, pDescription, pMarque, pPrix);
grammage = pGrammage;
}
public String toString() {
return super.toString()+", grammage= "+this.grammage;
}

Enseignante : Mme JAOUANI Page 110


L2

package com.poo.exam;

public class ArticleException extends Exception {

public ArticleException(String mes) {


super(mes);
}
}

package com.poo.exam;

public class Lot implements IFacturable {

public int nbArticles;


public Article[] articles;

public Lot(int nbArt) {


nbArticles = nbArt;
articles = new Article[nbArticles];
}

public Article getArticle(int i) {


return articles[i];
}

public boolean ajouterArticle(Article a, int indice) throws


ArticleException {
boolean add = false;
if ((indice < 0) || (indice > nbArticles))throw new
ArticleException("Article ne peut pas être pas ajouté");
else {
articles[indice] = a;
add = true;
}
return add;
}

Enseignante : Mme JAOUANI Page 111


L2
public boolean supprimerArticle(int indice) throws ArticleException {
boolean sup = false;
if ((indice < 0) || (indice > nbArticles))throw new
ArticleException("Article ne peut pas être pas supprimé");
else {
articles[indice]=null;
sup = true;
}
return sup;
}
public double calculerFacture() {
double facture = 0;

for(int i=0;i<nbArticles;i++) {
if(articles[i]!= null) {
facture += articles[i].prix;
}
}
return facture;
}

package com.poo.exam;

public class TestLot {

public static void main(String[]args) {


Lot a = new Lot(10);
try {
// 7 stylos
a.ajouterArticle(new Stylo(1,"stylo","bic",1.0,5),0);
a.ajouterArticle(new Stylo(1,"stylo","bic",1.0,5),1);
a.ajouterArticle(new Stylo(1,"stylo","bic",1.0,5),2);
a.ajouterArticle(new Stylo(1,"stylo","bic",1.0,5),3);
a.ajouterArticle(new Stylo(1,"stylo","bic",1.0,5),4);
a.ajouterArticle(new Stylo(1,"stylo","bic",1.0,5),5);
a.ajouterArticle(new Stylo(1,"stylo","bic",1.0,5),6);
// 3 Ramette papier

Enseignante : Mme JAOUANI Page 112


L2
a.ajouterArticle(new Stylo(1,"Ramette
papier","Paperus",6.0,3),7);
a.ajouterArticle(new Stylo(1,"Ramette
papier","Paperus",6.0,3),8);
a.ajouterArticle(new Stylo(1,"Ramette
papier","Paperus",6.0,3),9);
}catch(ArticleException e) {
System.out.println(e.getMessage());
}
// afficher les articles
for(int i=0;i<a.nbArticles;i++) {
if(a.articles[i]!=null)
System.out.println(a.articles[i]);
}
// afficher la facture des articles
System.out.println("La facture est de : "+a.calculerFacture()+"
dinars ");
// supprimer un article
try {
a.supprimerArticle(1);
}catch(ArticleException e) {
System.out.println(e.getMessage());
}
System.out.println("La facture après suppression de l'article 1 est
de : "+a.calculerFacture()+" dinars ");
}

============================ FIN=============================

Exercice 2 : (5 points, 30 min)

package com.poo.exam;

Enseignante : Mme JAOUANI Page 113


L2
public class Medecin {

public String nom;


public String prenom;

public Medecin(String pNom, String pPrenom) {


nom = pNom;
prenom =pPrenom;
}

public String toString() {


return prenom+" "+nom;
}
}

package com.poo.exam;

public class MedecinDeFamille extends Medecin{


int nbFamilles;

public MedecinDeFamille(String pNom, String pPrenom, int nb) {


super(pNom,pPrenom);
nbFamilles = nb;
}

public String toString() {


return super.toString()+", nombre de familles en charge
:"+nbFamilles;
}
}

package com.poo.exam;

public class Chirurgien extends Medecin {

public String specialite;


public Chirurgien(String pNom, String pPrenom, String pSpecialite) {
super(pNom, pPrenom);

Enseignante : Mme JAOUANI Page 114


L2
specialite = pSpecialite;
}

public String toString() {


return super.toString()+", specialite :"+specialite;
}
}

package com.poo.exam;

public class TestMedecin {


public static void main(String[] args) {
Medecin m = new Medecin("Ali","BA");
MedecinDeFamille mf = new MedecinDeFamille("Sami","BA",10);
Chirurgien c = new Chirurgien("Sonia","Ben
Salah","Dematologie");
System.out.println("Medecin: "+m);
System.out.println("Medecin de famille: "+mf);
System.out.println("Chirurgien: "+c);
}
}

Enseignante : Mme JAOUANI Page 115


L2

Bibliographie
[1] : « JAVA 6 Les fondamentaux du langage java » Thierry GROUSSARD, édition ENI Mars 2009

[2 ] : C.S. Horstmann, G. Cornell, au cœur de Java 2, Campus Press 2005.


[3 ] : E. Puybaret, Les cahiers du programmeur swing, Eyrolles 2006.
[4 ] : J. Hunter, Servlet Java, Oreilly 2002.

[5] : http://www.jmdoudoux.fr/java/dej/index.htm

[6] : www.Technologuepro.com

[7] : http://java.developpez.com/

Enseignante : Mme JAOUANI Page 116

Vous aimerez peut-être aussi