Académique Documents
Professionnel Documents
Culture Documents
Programmation Orientée Objet PDF
Programmation Orientée Objet PDF
OFPPT
RESUME THEORIQUE
&
GUIDE DES TRAVAUX PRATIQUES
MODULE N°4 :
SECTEUR : Tertiaire
SPECIALITE : Technicien Spécialisé en Développement Informatique
NIVEAU : TS
Septembre 2006
REMERCIEMENT
La DRIF remercie les personnes qui ont contribué à l’élaboration du présent document.
Pour la supervision :
Pour la conception :
Pour la validation :
Said Slaoui
DRIF
OBJECTIF OPERATIONNELS DE PREMIER NIVEAU
DE COMPORTEMENT
PRECISIONS SUR LE COMPORTEMENT CRITERES PARTICULIERS DE
ATTENDU PERFORMANCE
Algorithmes
Programme
Dans la programmation traditionnelle (années 70 et 80) un programme faisait appel à des fonctions ou
procédures ( en PASCAL) qui traitaient des données ou des structures de données (plus généralement). Le
principe était de trouver l'algorithme puis ensuite de trouver la structure de donnée la mieux appropriée pour le
passage de paramètre aux différentes fonctions. Cette programmation rendait la structure de données "fragile" car
n'importe quelle fonction pouvait accéder et changer les champs de cette structure . De plus la réutilisation du
code de certaines fonctions était difficile car rien n'était compartimenté.
Dans la programmation objet chaque paquets de données (qui aurait fait parti d'une structure en
programmation classique) est dans une classe. Les différents traitements à réaliser sur ces données sont faits par
des fonctions appartenant à la classe. L'accès aux données ne se fera que par des fonctions de la classe. Le fait de
compartimenter le code et les données dans une classe permet la réutilisation du code.
Exemples :
Classe Bateau : champs : Capitaine, type, couleur, position, vitesse,…
Fonctions ou méthodes : marche, stop, plus_vite, moins_vite
Classe Fenetre champs : positionX,positionY,TailleX,TailleY,Couleur,Nom,…
Fonctions ou méthodes : Créer, Réduire,Fermer,Déplacer, …
Avantages de la P.O.O.
Une classe peut hériter d'une autre classe ce qui permet d'utiliser les fonctions et les données de la
classe parent et de rajouter les données et fonctions de la nouvelle classe( en programmation
graphique toute nouvelle fenêtre windows est un objet hérité de la classe Fenetre dans laquelle on va
rajouter le code et les données de l'application).
Les fonctions de la classe n'ont pas un grand nombre d'arguments puisque les données sont lisibles par
les fonctions de la classe.
Grâce à la P.O.O., on gagne en rapidité de fabrication du code, puisqu'il est possible d'utiliser un
grand nombre de classe déjà existante.
Exemple :Le type abstrait Personne
struct Personne { /* une personne est décrite par son nom et sa société */
char Nom[25];
char Societe[32];
};
Vocabulaire et définitions
Un objet est caractérisé par ses informations et ses comportements : en programmation, on dira qu’un objet
encapsule données et traitements.
Un objet reçoit des messages qui déclenchent ses comportements.
La programmation orientée objet apporte une sécurité supplémentaire par rapport à la programmation
classique puisque l’objet contrôle chacun des comportements qui lui sont propres.
Les propriétés des objets de données et comportements semblables sont décrites par une même classe.
nom societe
deux instanciations
System.out.println(
"Je m'appelle " + nom); p2, un autre objet Personne
System.out.println(
"Je travaille à " + societe);
Les objets regroupés dans une même classe CCC sont appelés les instances de CCC.
Les données d’un objet sont ses variables d’instance.
Les comportements communs à toutes les instances sont représentés par des méthodes d’instance.
Maintenant, si on écrit :
Personne p = new Personne();
p.nom = "durand"; // nom en minuscules : la règle B n’est pas respectée
Le compilateur refuse la seconde instruction : p.nom, privée, est inaccessible pour l’utilisateur de la classe
Personne.
Ainsi il n'est plus possible de venir changer les données de la classe (ou propriétés) directement. On pourra
changer la valeur de ces propriétés à travers des méthodes qui vérifieront la justesse des informations entrées.
public les variables et méthodes d’une classe CCC, définies avec le modificateur public sont accessibles partout
où CCC est accessible.
private les variables et méthodes d’une classe CCC, définies avec ce modificateur ne sont accessibles que dans la
classe CCC.
Quand le concepteur de la classe n’a pas spécifié de mécanisme d’instanciation, Java en fournit un par
défaut, encore appelé constructeur par défaut.
Le constructeur par défaut initialise chaque variable d’instance vi avec une valeur par défaut :
- null si vi est de type objet,
- valeur par défaut du type ttt si ttt est un type primitif.
Définir un constructeur
class Personne {
private String nom;
private String societe;
public Personne (String leNom) {
nom = leNom.toUpperCase(); // cahier des charges, règle B
}
// etc. cf. page précédente
}
Avec le constructeur Personne(String) on peut instancier un objet Personne dont le nom est conforme aux
spécifications :
Personne p = new Personne("durand");
et on ne peut plus instancier d’objet de nom indéterminé :
Personne p = new Personne();// erreur de compilation : il n’y a plus de constructeur par défaut
Le constructeur est une des composantes importantes de la programmation objet. Toute nouvelle instance est
créée en utilisant un constructeur de clase.
Une nouvelle version de la classe
Dans cette nouvelle version, on retrouve le constructeur de la classe . Ce constructeur (même nom que la
classe) initialise les propriétés nom et societe de la classe Personne.
class Personne {
private String nom;
private String societe; // l’absence de société sera signalée par "?"
public Personne (String nom) {
// construit un objet Personne de nom invariable et de société inconnue
this.nom = nom.toUpperCase();
// qualification avec this pour distinguer la variable d'instance du paramètre
societe = new String("?");
}
public void presenteToi() {
System.out.println("Je m'appelle " + nom);
if (societe.equals("?"))
System.out.println("Je ne suis pas salarié");
else System.out.println("Je travaille à " + societe);
}
} // class Personne, deuxième version
Utilisation de this
Dans un constructeur, le mot-clef this désigne l'objet qui est construit.
Dans une méthode, ce mot-clef désigne l’objet qui traite le message :
Récapitulons
Le constructeur par défaut est encore appelé constructeur sans paramètres ou constructeur implicite.
Un constructeur est une méthode particulière, en général publique et dont l’identificateur est le même que
celui de la classe et qui est toujours définie sans type de renvoi.
Dès qu’un constructeur explicite est défini, le constructeur par défaut n’est plus disponible, sauf si le
programmeur le rétablit en définissant explicitement un constructeur sans paramètres.
Types primitifs et types objets
Dans la séquence
Personne p;
byte age; // aucune valeur de age n’est supérieure à 127
String prenom = "Delphine";
- la variable p est une référence non initialisée sur le type objet Personne,
- la variable age est une variable du type primitif byte,
- la variable prenom est une référence sur le type objet String, initialisée avec l’objet String "Delphine".
a = 245;
a 245
// on lui affecte la valeur 245
L’emplacement mémoire de la variable contient la valeur associée à la variable.
Une variable de type objet désigne sa valeur
String ch ; ch ?
// on déclare une référence de type String
ch = new String("Dupond" ) ; ch
// construction d’un nouvel objet String
// référencé par ch "Dupond"
L’emplacement mémoire de la variable contient une référence sur l’objet associé à la variable.
La valeur par défaut d’une référence est null, quel que soit le type objet associé.
affichera
a vaut 2360
b vaut 2356
Exemple d’exécution
{ // bloc A
Personne p1 = null;
int age = 54;
Meunier
{ // bloc B
Personne p2 = new Personne("Meunier"); ?
p2.presenteToi();
p1 = p2; tas
} // fin bloc B
... // etc. Bloc B P2
} // fin bloc A
Bloc A P1 54
pile
Définissons des accesseurs
Les méthodes taSociete et vaDansSociete sont respectivement des accesseurs en consultation et en modification
de la variable d'instance societe.
Un deuxième constructeur
public Personne (String nom, String entrep) {
// construit un objet Personne de nom fixe et de société connue
this.nom = nom.toUpperCase();
societe = valideSociete(entrep).toUpperCase();
}
Notion de signature
Pour le compilateur, il n'y a pas d'ambiguïté entre les deux constructeurs. Ainsi, l’exécution de :
new Personne("Meunier", "outils java");
fait appel au deuxième constructeur car celui-ci utilise deux chaînes en paramètre.
Plus généralement, la signature d’un constructeur ou d’une méthode comprend son identificateur, la liste et les
types de ses paramètres. Le compilateur détermine la méthode à exécuter en fonction de sa signature.
Des méthodes différentes peuvent porter le même nom, à partir du moment où leurs signatures diffèrent.
Modificateurs static et final
class Personne {
private String pasDeSociete = "?";
private String nom;
private String societe;
... // etc.
}
class Personne {
private static final String pasDeSociete = "?";
private String nom;
private String societe;
... // etc.
}
final ce modificateur impose que la définition comporte une valeur d'initialisation et empêche toute
affectation ultérieure d'une autre valeur. Il permet de définir une information constante.
static ce modificateur indique que toutes les instances de la classe se partageront un exemplaire
unique : une variable de classe.
Définition
On peut parfois souhaiter disposer de données communes et accessibles à toutes les instances d’une même classe.
Une variable permanente et unique pour toutes les instances d’une même classe s’appelle une variable de
classe.
Une méthode de classe représente un comportement associé à la classe elle-même et non pas à une instance
particulière de cette classe.
En Java, une variable de classe ou une méthode de classe, est définie avec le modificateur static.
class Personne {
// variables de classe
private static final String pasDeSociete = "?";
private static String nomDuFichier;
// méthodes de classe
public static void choisirFichier() {
}
// etc.
}
Exemple d'utilisation
La classe System fournit une variable de classe publique, out, que l'on exploite dans l'instruction suivante :
System.exit(0);
Comment exécuter une classe ?
Pour qu’une classe puisse être exécutée, il faut qu’il y ait la fonction :
public static void main( String [] arg){
// code du programme
}
Une autre solution consiste à placer la fonction main() dans la classe Nom et à créer une instance de la
classe Nom dans la fonction main().
Class Nom{
// variables de la classe privées ou publiques
// méthodes de la classe privées ou publiques
Enfin il est possible de tester les méthodes de la classe, sans faire une instanciation de la classe Nom. Il suffit
de déclarer les méthodes en static (déconseillé en général). Attention, des méthodes statiques ne peuvent
manipuler que des variables statiques.
Class Nom{
// variables statiques de la classe privées ou publiques
// méthodes statiques de la classe privées ou publiques
Remarque : Il est possible d’appeler une méthode dans une méthode de la classe, sans pour autant être obligé
de déclarer cette méthode en static. Seule la fonction main() demande cette condition.
Lancer un exécutable
Une fois le fichier source nom.java créé, il faut générer un fichier pseudo-exécutable nom.class (commande
javac nom .java) puis lancer cet exécutable : java nom. Il faut pour cela avoir au préalable télécharger le
jdk1.3 sur le site de http//www.sun.com.
Récapitulons…
méthode d’instance : les méthodes sont publiques si elles doivent être appelées de l’extérieur et privées si
elles ne sont appelées que par des méthodes internes à la classe.
L’objet est un paramètre implicite de la méthode, accessible si nécessaire via la notation this. Ainsi
l’accés à une variable (ou à une méthode) se fait par variable ou par this.variable.
Conventions d’écriture
Jusqu’à présent, pour des raisons pédagogiques, nous avons personnifié les messages et donné aux méthodes
des identificateurs dont le libellé illustrait le mécanisme : l’objet reçoit et traite le message :
tonNom, quitteTaSociete, etc.
Dans la pratique professionnelle, on utilise une forme moins personnifiée des notations, en utilisant plutôt
des verbes à l’infinitif
quitterSociete au lieu de quitteTaSociete
afficherEcran au lieu de presenteToi
Conseils
De même, pour les accesseurs, il est conseillé d’adopter les préfixes get et set : getNom au lieu de tonNom,
setSociete au lieu de vaDansSociete ;cette convention est celle attendue par la technologie des JavaBeans,
pour retrouver dynamiquement ces accesseurs
Version finale de la classe Personne
class Personne {
private static final String pasDeSociete = "?";
private String nom;
private String societe;
length()
curseur de fin
a e i o u y ? ? ?
Exemple
class TestStringBuffer{
public static void main(java.lang.String[] args) {
StringBuffer s= new StringBuffer("toto");
s.setCharAt(1,'i');
s.setCharAt(3,'i');
System.out.println(s);
s.insert(0,"coucou ");
System.out.println(s);
s.setLength(7);
System.out.println(s);
s.deleteCharAt(0);
System.out.println(s);
s.append(12);
System.out.println(s);
System.out.println("capacité:"+s.capacity()+"longueur:"+ s.length());
s.setLength(s.capacity());
System.out.println(s);
System.out.println("capacité:"+s.capacity()+"longueur:"+ s.length());
}
}
résultat :
titi
coucou titi
coucou
oucou
oucou 12
capacité:20longueur:8
oucou 12
Récapitulatif
Méthodes de Explications
StringBuffer
charAt(int) renvoie le caractère dont l’indice est précisé.
append(String) ajoute un ensemble de caractères à partir de l’indice référencé par le curseur de fin.
append(int) ajoute la chaine de caractère de l'entier (exemple append(12) ajoute la chaine "12")
append(float) ajoute la chaine de caractère du flottant (exemple append(12.5) ajoute la chaine
"12.5")
insert(int, String) insère une chaîne de caractères à l’indice précisé.
setCharAt(int, char) remplace le caractère dont l’indice est précisé.
reverse() inverse le sous-buffer de caractères compris entre l’indice 0 et l’indice référencé par le curseur de fin.
toString() renvoie un objet String.
String s;
s= "coucou"; "coucou"
s=s+"Au revoir";
"coucouAu revoir"
Dans l'exemple ci-dessous, il y a construction d'une référence sur la chaine "coucou". La méthode append
(qui n'existe pas pour la classe String) permet la concaténation de la chaine "coucou" avec la chaine
"Aurevoir". La référence sur l'objet s n'a pas changée.
StringBuffer s;
s("coucou"); "coucouAu revoir"
s.append("Au revoir");
Comprendre l’opérateur + de la classe String.
♦ Un objet String est un objet constant : toute méthode d’instance de String qui modifie le contenu d’une
chaîne de caractères renvoie une référence sur un nouvel objet String.
: avec les StringBuffer, on ne peut pas comparer le contenu des objets mais uniquement les objets, du coup
ils les convertir en String (toString()) afin de pouvoir comparer leur contenu.
Analyse
//ce programme est tiré de Comment Programmer en Java de Deitel & Deitel chapitre 10
import javax.swing.*;
System.exit( 0 );
}
}
♦ Commenter et expliquer ce programme
//ce programme est tiré de Comment Programmer en Java de Deitel & Deitel chapitre 10
// Les méthodes charAt, setCharAt, getChars, et reverse de la classe StringBuffer.
import javax.swing.*;
buf.setCharAt( 0, 'B' );
buf.setCharAt( 9, 'V' );
sortie += "\n\nbuf = " + buf.toString();
buf.reverse();
sortie += "\n\nbuf = " + buf.toString();
System.exit( 0 );
}
}
Exercices
♦ Ecrire une application qui lit une date sous la forme 25/04/1955 et qui la remplace en 24 Avril 1955, et vice
versa. L'utilisateur aura le choix d'entrer la date sous une forme ou une autre.
♦ Ecrire un programme qui vient lire une suite d'octets séparés par des points et les remplace par leur
équivalent hexadécimaux :
Exemple : 1.255.10 ⇒ 1 FF A
Ce programme sera fait:
En utilisant la méthode toHexString() de la classe Integer
Integer.toHexString(255).toUpperCase() // affiche FF
Ecrire la classe IntegerP
On désire écrire la classe IntegerP. Cette classe doit nous permettre de faire les conversions :
La classe StringTokenizer
On désire écrire le code de la classe StringTokenizer qui existe dans le package java.util. Cette classe
permet la découpe d'une chaine (champs str) en jetons en fonctions de caractères de délimitation (champs
delimiters). Ainsi si l'on place les délimiteurs = "\t\n\r .':", la chaine str="Bon jour.c'est:moi toto" sera
découpée en 6 jetons :
"Bon" "jour" "c" "est" "moi" "toto".
Exemple :
import java.util.*;
class Test{
public static void main(String [] arg){
String chaineADecouper = new String( "ceci est une test");
StringTokenizer jetons = new StringTokenizer( chaineADecouper );
System.out.println( "Nombre d'éléments: " + jetons.countTokens() + "\nLes jetons sont:\n" );
Résultat:
Nombres d'éléments : 4
Les jetons sont :
ceci
est
un
test
La classe StringTokenizer :
class StringTokenizer{
private int currentPosition;
private int maxPosition;
private java.lang.String str;
private java.lang.String delimiters;
Un individu peut avoir un département de résidence ou de travail, qui sera lui aussi invariable. Ce
département est un entier de 1 à 95.
private void setDepartement(int unDept) { ... // ici on rejette tout numéro de département incorrect
departement = (byte) unDept;
}
public Individu (String leNom, int leDept) {
nom = leNom.toUpperCase();
setDepartement(leDept);
}
// On définit un constructeur par défaut
public Individu () {
this("nom inconnu",0);//appel au constructeur Individu(String leNom,int leDept)
}
public void afficherSurEcran() {
System.out.println("Je m'appelle " + nom);
if (departement != 0)
System.out.println("j'habite dans le " + departement);
}
} // class Individu
Exercice :
Changer la fonction setDepartement pour ne ranger dans la donnée departement que des numéros
compris entre 0 et 95.
La classe Employe
Un employé a une société qui peut changer. Le nom de la société doit être en majuscules.
Définition
Une classe représente une famille d’objets ayant les mêmes propriétés et les mêmes méthodes.
L’héritage permet de reprendre les caractéristiques d’une classe existante MMM pour les étendre et définir
ainsi une nouvelle classe FFF qui hérite de MMM. La classe MMM est la classe mère et FFF est la classe
fille.
C la s s e m è r e
classe fille extends mere
h é rita g e {
// code
C la s s e f ille
}
Une classe fille ne peut hériter que d’une seule classe mère. On parle d'héritage simple. (En C++, il existe la
notion d’héritage multiple, c’est à dire une classe fille hérite de plusieurs classes mères).
Une classe fille peut elle-même être la classe mère d’une nouvelle classe. Plus généralement la classe C1 est
une superclasse de C2 (ou C2 est une sous-classe de C1) si C2 descend de C1, par une liaison d’héritage.
Individu
Employe Patron
Ici la classe Individu qui possède un nom et un numéro du département (où vit l'individu) est la classe mère (ou
superclasse) des classes Employe et Patron qui possèdent en plus des champs et méthodes de la classe Individu,
les champs societe (String Societe pour l'employé et String[] societe pour le patron qui peut posséder plusieurs
sociétés). La classe Employe peut elle-même être la classe mère des classes Cadre et Ouvrier.
A la définition de la classe, on utilise le mot-clé extends pour désigner la classe-mère. Par défaut, si le mot-
clé extends est omis, la classe hérite de la classe Object.
La classe Object est la superclasse de toutes les classes : en Java, la hiérarchie de classes est une arborescence
de racine unique.
Héritage et constructeurs
L'objet e se présente comme s'il était un Individu car il hérite de la méthode afficherSurEcran. On obtient
l’affichage :
Sans qu'on l'ait précisé dans le constructeur de Employe, la variable d’instance nom a pris la valeur "nom
inconnu". En effet, pour construire l’instance de Employe, le compilateur appelle d’abord le constructeur par
défaut de la classe Individu :
public Individu () {
nom = "nom inconnu";
departement = 0;
}
Si on supprimait ce constructeur de la classe Individu, on aurait alors, pour new Employe("CNAM"), le message
d'erreur suivant :
no constructor matching Individu() found in Individu
Remarque : super est le mot-clé pour désigner l'appel au constructeur de la super classe (ou classe mère).
Redéfinir une méthode héritée
Dans la redéfinition d'une méthode mmm, il est conseillé d'appeler la méthode mmm héritée (sauf si l'on veut
supprimer le comportement hérité). Ainsi, le mécanisme de l'héritage facilite la gestion des mises à jour de
mmm.
Mot clé final
Le mot clé final selon qu’il est appliqué à une donnée ou à une méthode n’a pas le même sens :
Le modificateur final empêche la redéfinition d’une méthode dans les classes dérivées.
Le mot clé final appliqué à une donnée déclare cette donnée comme constante.
On peut tout de même trouver une ressemblance entre les 2 sens du mot clé final :
Une fois qu’une variable a été déclarée en final, celle-ci ne peut plus être changée.
Une fois qu’une méthode a été déclarée en final, celle-ci ne peut plus être changée (par une
redéfinition dans sa classe fille.
Exemple :
Class EssaiMere {
Class Essai1 { public final void methfinal(){
public static final char NL = '\n'; System.out.println(“classe mere”);
public static final int AS = 1; }
public static final int VALET = 11; }
public static final int DAME = 12;
// declaration des methods
Class EssaiFille extends EssaiMere{
}
Public final void methfinal(){
// erreur de compilation
Expliquer le sens des mots clés static ajoutés aux }
mots clés final (Cf Chapitre 2.16)
Les références this et super ?
La référence super permet à un objet de référencer les variables et les méthodes de sa classe-mère.
Exemple : On désire créer une classe Point et une classe PointCol qui hérite de Point (point coloré)
Remarque:
Il n'y a pas d'héritage pour les variables de la classe fille ayant le même nom que ceux de la classe
mère. Dans ce cas, les variables de la classe fille cache les variables de la classe mère. Dans le cas des
méthodes, les méthodes de la classe fille surchargent celles de la classe mère.
class Mere {
Number aNumber;
}
class Fille extends Mere {
Float aNumber;
}
La variables aNumber cache la variable aNumber de la classe Mere. Cependant il est possible dans la
classe fille (Fille) de lire la variable aNumber de la classe mère. Il suffit d'utiliser le mot clé super. super
permet de préciser la référence de l'objet comme étant celle de la classe mère.
Le compilateur signale une erreur de compilation. En effet, la méthode setDepartement de Individu, parce
qu'elle est private, est inaccessible, même pour les sous-classes de Individu.
class Individu {
private String nom; // nom de l'individu
private byte departement; // département de résidence
// Cf CH 3.1 pour le détail des méthodes
}
Ces propriétés ne sont pas accessibles dans les méthodes de la classe Employe (classe fille de la classe
Individu).
Le modificateur protected permet de conserver une protection semblable à celle assurée par le modificateur
private, tout en assurant l'accès dans les classes héritées et les classes du même package.
Remarque : Une bonne conception objet ne doit jamais modifier une classe mère pour les besoins de la
définition d’une classe fille. Le concepteur de la classe mère doit prévoir les besoins de l’héritage et définir
les accès.
en conséquence. Souvent d’ailleurs, le choix d’un accès protected correspond à une solution de facilité, qui
n’est pas forcément la meilleure.
Il aurait été plus judicieux dans notre exemple d'utiliser directement la fonction
setDepartement héritée de la classe individu . En effet la fonction ChangerDepartement n'apporte rien de
plus.
la méthode setSociete de la classe Employe est déclaré en protected (au cas ou on aurait à hérité de la
classe Employe ,elle reste visible dans la classe fille).
L’appel au constructeur dans un constructeur ne peut se faire qu’avec le mot clé this :
public Employe (String leNom, String laSociete) {
this(leNom,laSociete,0); // appel au constructeur Employe(leNom,laSociete,0)
}
protected ou private ?
Utilisation du modificateur protected : dans ce cas la variable maVar reste visible dans les classes filles.
class CCC {
protected typeVar maVAR;
// MAVar visible uniquement dans les sous classes de CCC
...
} // class CCC
Utilisation d'accesseurs : dans ce cas la variable maVar est invisible. Par contre l’accés à cette variable
peut se faire par l’intermédiaire de ses accesseurs.
class CCC {
private typemaVar maVar; // maVar n’est pas accessible directement hors de CCC
...
private final typeMaVar valideMaVar(typeMaVar v) { // contrôle la validité pour maVar
... // tests de validité : v est-elle une valeur acceptable pour maVar ?
return v;
}
protected typeMaVar getMaVar() { // accesseur en consultation
return maVar;
}
protected void setMaVar(v) { // accesseur en modification
this.maVar = valideMaVar(v);
}
} // class CCC
La deuxième solution est plus contraignante pour le concepteur de la classe. Mais elle permet un contrôle de
validité sur les variables d'instances, et assure ainsi une plus grande sûreté dans l'utilisation de la classe.
Version finale de la classe Employe
class Employe extends Individu {
protected String societe; // nom de la société où l'employé travaille
Exercices
On désire rajouter une donnée numSecu qui comporte 13 numéros. Par exemple : "1681046068948"
Travail à faire :
ecrire la méthode String getInfo() qui renvoie le le nom, le sexe, l’age, la société
Cette classe met à jour ses champs lors de l'appel au constructeur. Ses champs étant public, il est alors facile
de connaitre l'age, la date de naissance (sous la forme "MM/AAAA")
Cette nouvelle classe possède les mêmes méthodes. Les méthodes getAge, ismasculin, getDateNaissance, le
constructeur Personne et setNumSecu utilise les propriétés de l'objet numSecu et le constructeur de la classe
NumSecu.
Personne
Personne
private String nom ;
private String societe ;
private NumSecu
numSecu;
public Personne (String nom)
public Personne (String nom, String Entreprise)
public Personne (String nom, String Entreprise, String NumSecu);
Créer la classe Ouvrier, la classe Cadre et la classe Patron qui héritent de la classe Personne. et prévoir les
constructeurs (à 3 et à 0 arguments) de chacune des 3 classes,
Ecrire la méthode float getSalaire() qui permet de calculer le salaire pour chacune des classes.
Ecrire la méthode String getInfo() qui renvoie le nom, le sexe, l’age, la société , le salaire et le poste occupé
(On pourra utiliser la méthode getInfo() de classe mère et rajouter l'information du poste occupé).
Le programme principal devra créer 1 patron et 2 cadres aux indice E1 et E3 et 5 ouvriers. Tester les
différentes fonctions.
Afficher les informations concernant les différents employés. Peut-on utiliser une boucle for ?
Si l’on essaie de comprendre ce qui s’est passé : à l’appel de la méthode getInfo() de la classe mère, Java
cherche la référence de l’objet e[i]. Si cette référence correspond à une classe fille (les classes Ouvrier,
Cadre ou Patron) alors il y a appel de la méthode de la classe fille. On dit que l’édition de lien est
dynamique (polymorphisme) puisque le choix de la méthode n’est pas fait lors de la compilation mais
au moment de l’appel de la méthode.
L’intérêt du polymorphisme est évident dans cet exemple puisque au lieu d’appeler 8 fois la méthode
getInfo() pour chaque objet, il suffit de faire l’appel dans une boucle.
Redéfinir une méthode : récapitulons
Si Fille est une classe qui hérite de Mere, une méthode m de Fille qui redéfinit m de Mere doit avoir la même
signature et le même type de renvoi :
class Mere {
public int renvoieCinq() { return 5; }
... // etc.
} // class Mere
Une méthode private est implicitement final. Si on redéfinit les méthodes renvoieCinq comme suit :
class Mere {
private int renvoieCinq() { return 5; }
... // etc.
} // class Mere
le compilateur Java ne considère pas la méthode renvoieCinq de Fille comme une redéfinition de
renvoieCinq de Mere, mais comme une nouvelle méthode.
Modificateurs d’accès
Il est possible d'élargir l'accès aux méthodes et aux variables d'instance à travers l'héritage.
Une méthode private n'est jamais accessible par les sous classes et ne peut donc pas être redéfinie (au sens
objet du terme)
Une méthode protected peut être redéfinie protected ou public (élargissement de l'accès)
Redéfinitions multiples
Quand une méthode mmm est redéfinie plusieurs fois, on ne peut, dans une redéfinition, accéder qu’à la
redéfinition immédiatement supérieure (via super).
En revanche, pour une variable d’instance plusieurs fois redéfinie, on peut avoir accès aux différentes
versions.
Le polymorphisme
La classe Fille qui hérite de la classe Mere prend les caractéristiques de cette dernière tout en ayant des propriétés en
plus
mMere()
Classe Mere
mRedef()
héritage
Revenons au cas classique où l'on crée 2 objets objM et objF en utilisant les constructeurs de chacun des 2:
Tas d'allocation
mRedef() mRedef()
mMere() mFille()
3 2
Table de Table de 10
Pile
Mere (3); fonction de fonction de
objM objF
Mere Fille Fill (2 10)
Pile
Le compilateur crée dans le tas d'allocation les variables de chaque objet et la référence des ses fonctions
membres (sauf si l'on précise le mot-clé final avant les fonctions).
à l'exécution
mRedef() mRedef()
mMere() mFille()
3 2
Pile Table de Table de 10
Mere (3); fonction de fonction de objF
objM
Mere Fille Fill (2 10)
Pile
le compilateur regarde les fonctions définies dans Mere et Fille. Pour ces fonctions, la connexion se fera lors
de l'exécution . Pour le reste, le compilateur place les références des fonctions. Ainsi les fonctions disponibles
sont mMere() et mRedef() pour l'objet objM.
De plus, seule la variable a est initialisé à 3 (la variable b appartient à Fille et est donc perdue).
Attention :Un objet Fille peut être considéré comme un objet Mere. Mais pas l’inverse
Exemple :
public class TestMereFille {
public static void main (String agrg[]){
Mere mere = new Mere(3);
Fille fille = new Fille(2,5);
mere= fille;
System.out.println("mere.a= "+mere.a);
mere.mRedef();
// System.out.println("mere.b= "+mere.b); Erreur de compilation
mere = new Mere(3);
// fille= (Fille) mere; //Erreur à l'exécution
mere.mRedef();
System.out.println("fille.a= "+fille.a);
System.out.println("fille.b= "+fille.b);
fille.mRedef();
((Mere)fille).mRedef();
}
}
mere.a= 2
Redef de fille
Redef de mère
fille.a= 2
fille.b= 5
Redef de fille
Redef de fille
Notion de classe abstraite
abstract
Personne float getSalaire() ;
private String nom ;
private String societe ; fonctions sans code ;
private String numSecu;
String getInfo() { //
Chaque animal est alimenté par une ration journalière calculée différemment selon qu’il s’agit d’un bovin,
d’un porcin ou d’un ovin.
On veut modéliser chaque population d’animaux en définissant une classe. Comment gérer les similitudes
entre les trois populations ?
une méthode descriptive toString, qui variera d’un animal à l’autre, avec une partie commune aux trois classes
une méthode definirRation, qui affiche la description de la ration journalière à attribuer à un animal : les trois
formes de cette méthode sont totalement distinctes les unes des autres.
La classe abstraite Animal : cette classe sera le point de départ de toutes les classes
abstract class Animal {
protected String identifiant;
protected int poids;
public Animal (String identifiant, int poids) {
this.identifiant = identifiant; this.poids = poids;
}
public String toString() {
return Identifiant + poids;
}
public abstract int definirRation();
} // class Animal
Hériter d’une classe abstraite
La classe Animal
Elle déclare la méthode abstraite definirRation : toute sous-classe de Animal devra définir cette méthode
pour être instanciable.
Solution 2 : On utilise une coquille à moitié pleine qui nous servira de moule pour l fabrication des autres
classes. Cette classe abstraite nous permet de définir des propriétés communes et surtout les méthodes
communes (avec le même code) et les méthodes abstraites (fournis sans le code, à définir dans les classes
filles).
definirRation()
identifiant
toString()
poids
Animal
la classe Animal est une classe abstraite et ne peut donc pas être instanciée,
definirRation() est une méthode abstraite, ce comportement doit être implémenté dans chaque sous-classe,
pour que celle-ci soit instanciable.
toString est une méthode non abstraite, c’est un comportement par défaut hérité par les sous-classes, mais elle
peut être redéfinie par les sous-classes
Remarque : une méthode avec le modificateur abstract ne doit pas être implémentée dans la classe de base
mais doit l’être dans les sous-classes
Exemple d’implémentation de la classe Animal et des classes Ovin, Bovin
abstract class Animal {
protected String identifiant;
protected int poids;
public Animal (String identifiant, int poids) {
this.identifiant = identifiant; this.poids = poids;
}
public String toString() {
return Identifiant + poids;
}
public String getIdentifiant(){ return identifiant;}
public int getPoids(){ return poids;}
pubic void setIdentifiant(String s){identifiant = s;}
public void setPoids(int poids){ this.poids=poids;}
des méthodes abstraites : elles sont déclarées avec le modificateur abstract mais ne sont pas définies : elles
jouent le rôle d’un outil de spécification, en forçant toute sous-classe instanciable à implémenter le
comportement correspondant,
des méthodes non abstraites, complètement définies, qui représentent soit des comportements par défaut pour
l’héritage, soit un comportement commun hérité.
Une classe est abstraite si elle est définie avec le modificateur abstract.
Elle peut déclarer 0 ou plusieurs méthodes abstraites.
Une méthode abstraite est déclarée (et non définie) avec le modificateur abstract.
Une classe CCC qui hérite d'une classe abstraite AAA doit implémenter toutes les méthodes déclarées
abstract, sauf si elle est elle-même abstraite. Si CCC n’est pas définie abstract, et si toutes les méthodes
abstraites héritées de AAA ne sont pas définies dans CCC, la compilation de CCC provoque une erreur.
Exercice :
abstract Personne
l
private String nom ;
private String societe ;
private NumSecu
public Personne (String nom)
public Personne (String nom, String Entreprise)
public Personne (String nom, String Entreprise, String NumSecu);
public String getNom();
public String getSociete();
public String getInfo();
public void setNom(String s);
public void setSociete(String societe);
public void setNumSecu(String numSecu);
public boolean etreSalarie() {
private String validerSociete(String sNom);
public abstract float getSalaire();
Expliquer.
La classe Object
On a vu précédemment que le mot clé extends permet de spécifier le nom de la classe mère. Si ce mot clé
extends n'est pas utilisé la classe dérive par défaut de la classe Object. Ainsi, les 2 lignes ci-dessous sont
équivalentes :
….
Point p=newPoint(11,2);
Point p1=newPoint(1,11);
p=p1; // p possède maintenant la même référence que p1.
…..
Si l'on veut recopier l'espace mémoire de l'objet p1 vers un autre espace mémoire et donner la
référence à p, il faut utiliser la méthode clone.
….
Point p=newPoint(11,2);
Point p1=newPoint(1,11);
p=p1.clone();// p récupère la référence de l'espace mémoire alloué par clone dans lequel x=1 et y=11
La méthode clone permet de recopier un objet ayant des propriétés de types primitifs. Mais pour les
propriétés de type objet, la méthode clone ne recopiera que la référence de l'objet, ce qui n'est pas suffisant :
class Vecteur {
Point a;
Point b;
Vecteur(int x,int y) {a = new Point(x,y); b=new Point(3,4);}
}
…
Vecteur monVect = new Vecteur(1,2);
Vecteur monVect1 = new Vecteur(3,4);
monVect=monVect1.clone( );
Avant
Vecteur monVect = new Vecteur(1,2); Vecteur monVect = new Vecteur(3,4);
après : monVect=monVect1.clone( );
if (one.equals(anotherOne))
System.out.println("objects are equal");
Résultat true : même si les objets one et anotherOne sont 2 objets différents. Normal puisque equals
compare les valeurs : ici 1=1.
Il faudra donc savoir si les propriétés sont de type primitifs (auquel cas ce sont les valeurs qui seront
comparées) ou des objets (auquel cas ce sont les références qui seront comparés, permet de vérifier que 2
objets ont la même référence). Si vous surdéfinissez equals il faut surdéfinir hashCode.
La méthode finalize :
La méthode finalize est appelé par le système lorsque l'on sort de la classe.
La méthode toString :
Cette méthode est très intéressante pour le déboggage. La plupart des classes redéfinissent cette
méthode.
La méthode getClass :
La méthode getClass est une méthode final qui permet de récupérer le nom de la classe. Ainsi la méthode
suivante permet d'afficher le nom de la classe de l'objet passé en argument.
Les interfaces
Une interface est une classe abstraite particulière. Elle ne définit aucune variable d’instance et toutes ses
méthodes doivent être abstraites. Une interface ne fait que représenter, sans les implémenter, un ensemble
de comportements. Elle a uniquement un pouvoir de spécification.
Une interface peut hériter de plusieurs interfaces. Elle rassemble alors les spécifications des interfaces mères :
interface Amphibie extends Terrestre, Marin
Une classe peut hériter d'une seule classe-mère et d'une ou plusieurs interfaces, dont elle fournit une
implémentation.
Les interfaces n’ont pas seulement un rôle de spécification, elles permettent d’avoir une « vue » particulière
sur un objet : un objet peut être casté dans le type d’une interface qu’il implémente.
Plusieurs objets implémentant la même interface pourront être considérés de façon équivalente à travers cette
interface.
On pourra alors passer indifféremment un objet Baleine ou un objet Tortue comme paramètre dans la
méthode suivante :
public void afficheAnimalMarin(Marin animal) {
System.out.println("Race : "
+ animal.getClass().getName());
System.out.println("Vitesse de nage : "
+ animal.vitesseDeNage());
}
Exercices :
la classe ColouredPoint
On désire créer la classe ColouredPoint qui hérite de la classe Point de l'exercice 2.24. Cette classe se définit
par
Class ColouredPoint extends Point{
protected java.awt.Color color;
ColouredPoint(int,int,Color){// à définir}
ColouredPoint(Point,Color){// à définir}
getColor(){// à définir}
Sous VisualAge, on pourra dans le WorkBench faire WorkSpace, OpenTypeBrowser et chercher Color :
pour comprendre cette classe.
De plus, il est impératif que la classe NomClasse se trouve dans le répertoire nomPackage.
Exemple :
Package P Compilation ClasseCP.class
ClasseB.class
Fichier 1 s
ClasseC.class
ClasseCP ClasseB
s
ClasseD.class
Fichier 2
ClasseC ClasseD
Le modificateur protected
L’accès à une propriété protected de la classe CCC est limité aux sous-classes de CCC et aux classes du
même package que CCC.
Modificateurs d’accès : récapitulatif
Dans l’exemple ci-dessous :
La classe C4 hérite de C1
Exemple
La classe Compte est définie dans le package PPP :
package PPP;
public class Compte {
protected float solde;
public void enregistreOperation(float versement) {
solde += versement; }
}
}
La classe Pel hérite de Compte. Elle est aussi définie dans le package PPP :
package PPP;
public class Pel extends Compte {
... // etc.
}
import PPP.Compte;
import PPP.Pel;
class Courant extends Compte {
public void mmm(Compte instanceClasseMere,
Courant instanceMemeClasse,
Pel instanceClasseSoeur) {
solde = instanceMemeClasse.solde; // OK
solde = instanceClasseMere.solde; // erreur de compilation
solde = instanceClasseSoeur.solde; // erreur de compilation
}
}
Un exemple de package : java.util
Un package peut contenir des classes, des interfaces ou d’autres packages (sous-packages).
Package java
java.util
java.util.zip java.lang
Vector
Dictionary
Object
Enumeration Hashtable
Hiérarchie de packages
L’arborescence des packages de la librairie standard Java est compressée dans le fichier classes.zip.
Package et modificateurs d’accès
Pas de modificateur : on parle d'accès package.La propriété (variable ou méthode) n'est accessible qu'aux
autres classes du même package,
Un package définit un espace de noms qui permet de résoudre les éventuelles ambiguïtés entre les noms
de classes. Par exemple :
java.util.Date et java.sql.DateExemples d'utilisation de packages
Découpage en packages
Les packages sont souvent utilisés pour matérialiser le découpage d’une application en couches abstraites
distinctes : la couche de gestion de persistance, la couche métier, l’interface graphique....
Les fichiers jar
Des librairies de classes peuvent aussi être utilisées. Elle sont stockées sous forme de fichiers compressés
à extension .jar. Exemple : swingall.jar
Pour pouvoir importer les packages des exemples précédents, le chargeur de classes doit trouver les
répertoires correspondants.
CLASSPATH = .;C:\Java1.1\Lib\Classes.zip;C:\package\mesComposants.jar;C:\package
Remarque:
On peut définir un CLASSPATH au niveau du système et/ou au niveau de l’environnement de travail
IV - Les structures de données
Introduction
Ce chapitre va nous permettre de comprendre les mécanismes de gestion de données. La gestion de
données , on le verra dans le chapitre suivant, peut se faire avec des classes (Vector, ..) fournis par Java.
Cependant , pour un programmeur débutant, il est important de comprendre les différents éléments mis en
jeu dans la gestion de structures de données.
Ma première base de données (les bases de données statiques)
On désire mettre en place une base de données statique de personnes travaillant dans une société.
Pour cela on reprend les classes définies dans le chapitre III.13. Cette base de données est appelée statique
car elle possède un nombre fixe de Personne.
La classe NumSecu
Cette classe a déjà été écrite dans l'exercice V.13.3. Cette classe permet de rentrer le numéro de
sécurité sociale de la Personne. Ce numéro est confidentiel et donc est déclaré en private. Invisible à
l'extérieur de la classe NumSecu. Ce numéro de sécu permet de connaitre l'age, le sexe et la date de
naissance (sous la forme "MM/AAAA"). Le numéro de sécu doit nous permettre de distinguer 2
personnes. Comme l'on veut que le programmeur n'ait pas accés à cette variable, nous allons coder le
numéro de sécu et le transformer en un entier.Le code associé au numéro de sécu est donné par la
fonction numCode().
NumSecu
private String numSecu;
public int age;
public String dateNaissance
public boolean Masculin
NumSecu
Une entreprise possède des salariés (ici fixé à 5). Ces salariés sont des Personne. Une Personne peut être un
Patron, un ouvrier ou un Cadre. Une Entreprise est donc un tableau de Personne.
L'Entreprise doit être capable de dire combien il y a de cadres, d'ouvriers et de Patrons dans l'entreprise et
donner leurs références
Dans un deuxième temps, on devra être capable de faire des recherches dans la base de données:
ainsi il sera possible de rechercher une personne par son nom, son age ou son numéro de sécu.
Remarque : il est possible en utilisant la méthode getClass() héritée de la classe object de récupérer la
classe de l'objet.
Entreprise
private Personne[] tabP;
private static final int
N=5;
public Entreprise();
public void ajouter (Personne p);
public void retirer (Personne p);
public void afficher();
public boolean isExiste(Persone p);
public boolean isPlein();
public boolean isVide();
public int chercher (Personne []p, String
salarie);
public void toutEffacer();
public int getNbPersonne();
Les méthodes de la classe Entreprise null
Le constructeur : null
null
public Entreprise(){ null
tabP = new Personne [N];
} Personne null
Méthode ajouter :
Pour ajouter une personne, il suffit de trouver une case vide. Dés que l'on trouve une cas vide, on ajoute la
personne et on sort de la méthode. Si la base est pleine, on affiche "base pleine" et on sort.
Attention, si la personne existe déjà dans la base, on ne doit pas la saisir de nouveau.
Méthode retirer
Pour retirer une personne de la base , il faut que cette base soit non vide et que cette personne soit
référencée dans la base. Dés que la personne est trouvée, on met sa référence à null. (effacée).
}
}
Methode toutEffacer :
Méthode afficher:
Si la base est non vide on affiche toutes les cases non vides , sinon on affiche ("base vide")
Methode isExiste:
Si la base est non vide on teste le code de la personne avec le codes de chaque référence de la base.
Méthode isVide :
Méthode isPlein
Cette méthode se base sur le fait que toutes la classe personne hérite par défaut de la classe Object, et donc
possède la classe getClass(). Si la référence est un objet de la classe Ouvrier, la méthode getClass() renvoie
: class cours.ouvrier (cours étant le nom du package). pour connaître la classe il faut donc analyser la
chaine de caractère renvoyée par la méthode getClass.
if(!isVide()){
for( i=0;i<tabP.length;i++){
if(tabP[i]!=null){
s=tabP[i].getClass().toString();
StringTokenizer t= new StringTokenizer(s," .");
while(t.hasMoreElements())
if(t.nextToken().equals(Salarie)) p[compteur++]=tabP[i];
}
}
}
utilisation de la méthode chercher : on veut afficher tous les ouvriers dans un tableau d'ouvrier
Un exemple récapitulatif
Dans ce qui suit , se trouvent les classes NumSecu, Personne et Entreprise. Ces classes ne sont données
qu'à titre indicatif et ne suivent pas compètement ce qui a été énoncé précédement.
Il est demandé d'écrire soit-même les classes en fonction du cahier des charges et de tester dans une classe
à part la base de données.
package cours;
package cours;
public Entreprise() {
tabP = new Personne [N];
}
L'insertion d'un salarié peut se faire à partir du premier noeud ou à partir du dernier noeud.
De plus , il doit être possible d'effacer dans un premier temps le premier ou le dernier salarié de la liste.
Remarque : dans un deuxième temps, ou pourra se poser la question de l'effacement d'un salarié
quelconque dans la liste.
Noeud Noeud
dernier
Premie salarie1 suivan salarie2 suivan Noeud
rNoeud
La Classe Liste
Reprenons le cahier des charges fixé au chapitre 2.3 pour la classe Entreprise:
Une entreprise possède des salariés (ici fixé à 5). Ces salariés sont des Personne. Une Personne peut être un
Patron, un ouvrier ou un Cadre. Une Entreprise est donc un tableau de Personne.
L'Entreprise doit être capable de dire combien il y a de cadres, d'ouvriers et de Patrons dans l'entreprise et
donner leurs références
Dans un deuxième temps, on devra être capable de faire des recherches dans la base de données:
ainsi il sera possible de rechercher une personne par son nom, son age ou son numéro de sécu.
On utilise les classes définies dans le chapitre 2.2, c'est à dire la Classe abstraite Personne et les classes
filles Employe, Cadre et Patron.
Liste
private NoeudListe
premierNoeud;
private NoeudListe
public Liste()
public Liste( String s )
public void afficher()
public boolean isVide()
public void insererEnQueue( Personne personneAIns )
public void insererEnTete( Personne personneAIns )
public Personne retirerDeQueue()
public Personne retirerDeTete()
public boolean isExiste(Persone p);
public int chercher (Personne []p, String salarie);
public void toutEffacer();
public int getNbPersonne();
Le constructeur : public dernier
Liste() Premie null null Noeud
rNoeud
Noeud Noeud
insertion du
dernier deuxième élément
Premie salarie suivan salarie1 suivan Noeud é l i 2
rNoeud 2
Noeud Noeud
insertion du
dernier deuxième élément
Premie salarie1 suivan salarie suivan Noeud é l i 2
rNoeud 2
Effacement en queue : public Personne retirerDeQueue()
Noeud Noeud
Liste avant l'appel à la
dernier méthode
Premie salarie suivan salarie1 suivan Noeud i D Q
rNoeud 2
Noeud Noeud
Liste avant l'appel à la
dernier méthode retirerDeTete
Premie salarie2 suivan salarie suivan Noeud
rNoeud 1
package cours;
package cours;
// Constructeurs
public Liste() {
this("liste");
}
// Insérer un salarie en queue de la Liste. Si Liste est vide, premierNoeud et dernierNoeud se réfèrent au
// même objet; sinon, la variable d'instance suivant du dernierNoeud fait référence au nouveau nœud.
public void insererEnQueue( Personne personneAIns ){
if ( isVide() )
premierNoeud = dernierNoeud = new NoeudListe( personneAIns );
else dernierNoeud = dernierNoeud.suivant = new NoeudListe( personneAIns );
}
// Insérer un Object en tête de la Liste. // Si Liste est vide, premierNoeud et dernierNoeud se réfèrent au
// même objet; sinon, le premierNoeud se réfère au nouveau nœud.
public void insererEnTete( Personne personneAIns )
{
if ( isVide() ) premierNoeud = dernierNoeud = new NoeudListe( personneAIns );
else premierNoeud = new NoeudListe( personneAIns, premierNoeud );
}
return retirerElement;
}
}
Le test de la structure de données dynamique
package cours;
objARetirer = entrepriseList.retirerDeTete();
System.out.println( objARetirer.getCode() + " retirer" );
entrepriseList.afficher();
objARetirer = entrepriseList.retirerDeTete();
System.out.println(objARetirer.getCode() + " retirer" );
entrepriseList.afficher();
objARetirer = entrepriseList.retirerDeQueue();
System.out.println(objARetirer.getCode() + " retirer" );
entrepriseList.afficher();
objARetirer = entrepriseList.retirerDeQueue();
System.out.println(objARetirer.getCode() + " retirer" );
entrepriseList.afficher();
}
}
le numéro de sécu de toto:221427589
le numéro de sécu de patron:0
le numéro de sécu de titi:140489389
le numéro de sécu :138837589
La CNAM contient:
Je m'appelle TOTOj'habite dans le 90 je travaille à IUT
La CNAM contient:
Je m'appelle PATRONj'habite dans le 90
Je m'appelle TOTOj'habite dans le 90 je travaille à IUT
La CNAM contient:
Je m'appelle PATRONj'habite dans le 90
Je m'appelle TOTOj'habite dans le 90 je travaille à IUT
Je m'appelle TITIj'habite dans le 90 je travaille à CNAM
La CNAM contient:
Je m'appelle PATRONj'habite dans le 90
Je m'appelle TOTOj'habite dans le 90 je travaille à IUT
Je m'appelle TITIj'habite dans le 90 je travaille à CNAM
Je m'appelle TUTUj'habite dans le 90 je travaille à CNAM
0 retirer
La CNAM contient:
Je m'appelle TOTOj'habite dans le 90 je travaille à IUT
Je m'appelle TITIj'habite dans le 90 je travaille à CNAM
Je m'appelle TUTUj'habite dans le 90 je travaille à CNAM
221427589 retirer
La CNAM contient:
Je m'appelle TITIj'habite dans le 90 je travaille à CNAM
Je m'appelle TUTUj'habite dans le 90 je travaille à CNAM
138837589 retirer
La CNAM contient:
Je m'appelle TITIj'habite dans le 90 je travaille à CNAM
140489389 retirer
La CNAM est vide.
Une autre structure de données dynamique : la pile
La pile (stack en anglais) est une version de la liste chainée précédente assortie de quelques
contraintes : les noeuds sont obligatoirement ajoutés et retirés de la pile à son sommet. Pour cette raison,
on désigne la pile comme une structure de données du type dernier entré, premier sorti, ou LIFO (Last In,
First out). Le membre de liaison qui porte le lien au membre suivant dans le dernier noeud de la pile est
mis à null pour indiquer qu'il constitue le pied de la pile.
Les principales méthodes qui interviennent dans la manipulation d'une pile sont les méthodes push
(pousser) et pop (enlever). La méthode push ajoute un nouveau noeud au sommet de la pile alors que la
méthode pop retire le noeud du sommet de la pile.
L'insertion d'un salarié peut se faire à partir du premier noeud (c'est le sommet de la pile)
De plus , il doit être possible d'effacer dans un premier temps le premier salarié de la liste.
Noeud Noeud
La Classe Pile
Dans sa forme la plus simple la classe Pile peut être implémentée à partir de la classe mère Liste.
Noeud Noeud
insertion du
Premie salarie salarie1 suivan deuxième élément
suivan
rNoeud 2 é l i 2
L'insertion d'un salarié se fait à partir du premier noeud (c'est le sommet de la pile)
Nous nous intéresserons dans un premier temps aux collections les plus anciennes , mais que l'on peut
toujours utiliser.
La classe Vector
Un Vector possède une taille (renvoyée par size()) et une capacité (renvoyée par capacity()). Le
constructeur par défaut créé un tableau de 10 éléments vide (taille=0 et capacité=10).
A chaque fois que la taille du tableau, lors de l'ajout d'un élément, excède la capacité de ce tableau, le
système double automatiquement la taille du tableau.
Remarque : setElementAt() ,Il faut que l’index passé en paramètre corresponde à une case qui « existe »...
Exercice :
Reprendre la classe Entreprise du chapitre VII 2.3 (structures de données) et utiliser la classe Vector pour
implémenter cette classe. On utilisera pour cela l'objet vectE de la classe Vector qui sera instancié dans le
constructeur Entreprise(). La classe Entreprise n'aura pas la méthode isPlein(), puisque cette fois-ci le
tableau utilisé est dynamique (principe de la classe Vector).
Entreprise
private Vector vectE;
public Entreprise();
Permet de chercher un groupe
public void ajouter (Personne p); de salarié de même type :
public void retirer (Personne p); "employé, cadre ou patron"
public void afficher();
public boolean isExiste(Persone p);
Cette méthode renvoie dans
public boolean isVide(); Personne[] p les salariés
public int chercher (Personne []p, String trouvés
salarie);
public void toutEffacer();
public int getNbPersonne();
Vecteurs et énumérations
L'interface Enumeration
L'interface Enumeration du package java.util définit un type abstrait qui déclare des services de contrôle
d’itération pour parcourir le contenu d’une collection d’objets.
Un exemple d’utilisation :
int i;
for (i = 0 ; i < monVecteur.size();i++)
monObjet := monVecteur.elementAt(i) ;
Remarque : ‘la méthode elements de Vector renvoie un objet dont le type implémente l’interface
Enumeration’ => les comportements hasMoreElements et nextElement se retrouvent chez tous les objets
qui implémentent Enumeration
La classe Stack
Au chapitre précédent nous avons appris comment construire des structures de données telles que
les listes chainées, les piles , les queues. Nous avions crées la classe Pile qui héritait de la classe Liste.
La classe Stack est implémentée à partir des méthodes de la classe Vector, et donc la classe Stack
hérite de la classe Vector. La classe Stack permet de réaliser une structure de données en pile. Cette classe
est comme la classe Vector conçue pour stocker des Object.
La classe Hashtable
Remarque :
Un dictionnaire est une collection d’associations clé-valeur. On accède à une association non pas avec un
index mais via une clé qui doit être du type objet.
Valeur
Clé
On n’a pas accès à l’ordonnancement des associations dans la table de hachage, c’est un algorithme
interne qui s’en charge. Du coup la première association que l’on a créée ne sera pas forcement celle que
l’on verra apparaître lors d’une itération sur la table.
Dictionnaires et énumérations
Un exemple d’utilisation
Collections génériques
Les méthodes d’accès aux éléments d’une collection renvoient des objets qui ne « connaissent » que les
méthodes génériques de Object :
elementAt(int index) de Vector
nextElement() de Enumeration
get(Object clé) de Hashtable
Remarque : on peut stocker n’importe quel type d’objets dans un vecteur et dans un dictionnaire.
En contrepartie, quand on veut travailler sur les éléments de ces collections, il faut préciser au
compilateur de quoi il s’agit.
...
//création de l'auteur Hergé
Vector livresHerge = new Vector();
Auteur auteurHerge = new Auteur("Hergé", livresHerge);
[ ... ] // ici, on enregistre des livres dans le vecteur livresHerge
Dans l’exemple :
livresHerge est un vecteur qui contient des chaînes de caractères.
On utilise une énumération de ce vecteur. La méthode nextElement renvoie un Object.
indexOf est une méthode de la classe String. Pour utiliser indexOf, on est obligé de faire un cast.
Remarque : Attention, ceci n’est pas forcément un avantage : on peut stocker des objets de types
différents, mais quand on les récupère, on ne sait pas forcément de quel type est l’objet récupéré (donc pb
pour le cast)...
...
for (int i=0; i<tableauLivres.length; i++)
if (tableauLivres[i].indexOf("Tintin") != -1)
nombre ++;
Les collections du JDK 1.2
La nouvelle version du JDK (JDK 1.2) intègre un ensemble de collections beaucoup plus complet que
celui de la version précédente. Ces collections sont classées en trois catégories représentées par les trois
interfaces:
iterator() : Crée une instance de la classe Iterator, utilisée pour itérer sur la collection avec possibilité de
suppression en cours de l’itération . L’itération est alors réalisée grâce aux méthodes hasNext(), next() et
remove() de la classe Iterator.
L'interface Collection :
public interface Collection {
// Basic Operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(Object element); // Optional
boolean remove(Object element); // Optional
Iterator iterator();
// Bulk Operations
boolean containsAll(Collection c);
boolean addAll(Collection c); // Optional
boolean removeAll(Collection c); // Optional
boolean retainAll(Collection c); // Optional
void clear(); // Optional
// Array Operations
Object[] toArray();
Object[] toArray(Object a[]);
}
La méthode iterator() renvoie une référence sur un objet implémentant l'interface Iterator qui
est équivalente à l'interface Enumeration de la classe Vector
Une collection est une structure de données, qui peut contenir d'autres objets. Les Interfaces des
collections définissent les opérations que l'on peut réaliser. Ces interfaces sont implémentés de différentes
manières, en fonction de différents buts recherchés
// Search
int indexOf(Object o);
int lastIndexOf(Object o);
// Iteration
ListIterator listIterator();
ListIterator listIterator(int index);
// Range-view
List subList(int from, int to);
}
Vector : un tableau redimensionnable synchronisé (cf chp. Thread).
ArrayList : un tableau redimensionnable, non synchronisé dont certaines fonctions
nécessitent un temps linéaire d’exécution (manque de performance pour des collections de
grande taille).
LinkedList : liste chaînée avec méthodes d’accès au premier et au dernier élément et
fournissant des méthodes de base pour l’implémentation des files d’attentes et des piles.
public CollectionTest()
{
ArrayList uneListe = new ArrayList();
retirerChaines( uneListe );
ArraySet : basée sur ArrayList , permet les éléments null et performante seulement pour
des petits ensembles.
La classe Arrays
Cette classe permet la manipulation de tableaux. La classe Arrays fournit des méthodes de recherche dans
un tableau trié (binarySearch), de comparaison de tableaux (equals), de remplissage de tableau (fill) et de
tri de tableau (sort).
public UtilisationTableaux()
{
rempliDInt = new int[ 10 ];
copieValeursInt = new int[ valeursInt.length ];
Arrays.fill( rempliDInt, 7 ); // remplir avec des 7.
Arrays.sort( valeursDouble ); // trier valeursDouble.
System.arraycopy( valeursInt, 0, copieValeursInt,
0, valeursInt.length );
}
System.out.print("\nvaleursInt: " );
for ( int k = 0; k < valeursInt.length; k++ )
System.out.print( valeursInt[ k ] + " " );
System.out.print("\nrempliDInt: " );
for ( int k = 0; k < rempliDInt.length; k++ )
System.out.print( rempliDInt[ k ] + " " );
System.out.print("\ncopieValeursInt: " );
for ( int k = 0; k < copieValeursInt.length; k++ )
System.out.print( copieValeursInt[ k ] + " " );
System.out.println();
}
public int rechercheUnInt( int valeur )
{
return Arrays.binarySearch( valeursInt, valeur );
}
u.afficheTableaux();
u.afficheEgalite();
int n = u.rechercheUnInt( 5 );
System.out.println( ( n >= 0 ? "Trouv‚ 5 … l'‚l‚ment " + n :
"5 introuvable" ) + " dans valeursInt" );
n = u.rechercheUnInt( 8763 );
System.out.println( ( n >= 0 ? "Trouv‚ 8763 … l'‚l‚ment "
+ n : "8763 introuvable" )
+ " dans valeursInt" );
}
}
méthode sort
import java.util.*
class NameSort {
public static void main(String args[]) {
String n[] = {"bobo","toto","titi"};
List l = Arrays.asList(n);
Collections.sort(l);
System.out.println(l);
}
}
Méthode shuffle
// Ce programme est tiré de l'ouvrage Deitel et Deitel : Comment Programmer en Java
// Utilisation de l’algorithme shuffle.
import java.util.*;
class Carte {
private String face;
private String coul;
tamp.setLength( 20 );
return ( tamp.toString() );
}
}
public Cartes()
{
Carte jeuDeCartes[] = new Carte[ 52 ];
public Algorithmes1()
{
laListe = Arrays.asList( lettres ); // obtenir liste.
copieLettres = new String[ 3 ];
copieListe = Arrays.asList( copieLettres );
public BinarySearchTest()
{
uneListe = new ArrayList( Arrays.asList( couleurs ) );
Collections.sort( uneListe ); // trier l’ArrayList.
System.out.println( "ArrayList trié: " + uneListe );
}
ArrayList trié: [blanc, bleu, brun_clair, jaune, mauve, noir, rose, rouge]
Exercices
Utilisation de StreamTokenizer
Ecrire un programme qui demande à l'utilisateur d'écrire une phrase. Cette phrase est analysée par la
classe StreamTokenizer puis placé dans une liste (ArrayList) sous le nom de list1.
Copier cette méthode dans list2.
On demande de classer (méthode sort()) cette liste puis de faire une recherche (méthode binarySearch())
d'un mot entré par l'utilisateur.
Reprendre list1 et remplacer toutes les occurences de "est" par "sont".
Créer un tableau de String de type Arrays et le remplir de "un".
Créer une Liste list3 qui prend la référence du tableau créé précédemment méthode asList().
Puis créer une liste de type HashSet() qui permet de ne créer que de mots différents à partir de list1.
Utilisation des classes ArrayList et HashTable dans la structure de données Entreprise vu au chapitre
VII
On désire reprendre les classes Personnes et les classes Ouvrier, Cadre et patron et reprendre la classe
Entreprise du chapitre VII.
On désire utiliser la classe HashTable qui permet d'entrer dans la structure un Objet suivi de sa clé. On
utilisera comme clé le numéro de sécurité sociale. Ce numéro de sécurité sociale est placé dans une
classe, pour permettre la conformité
La classe Entreprise
Une entreprise possède des salariés .Ces salariés sont des Personne. Une Personne peut être un Patron, un
ouvrier ou un Cadre. Une Personne est définie par sont numéro de sécurité sociale qui constitue sa clé dans
la structure de donnée. Une Personne ne peut pas se trouver 2 fois dans l'entreprise.
L'Entreprise doit être capable de dire combien il y a de cadres, d'ouvriers et de Patrons dans l'entreprise et
renvoyer une liste de Personne (du type List).
on devra être capable de faire des recherches dans la base de données: ainsi il sera possible de rechercher
une personne par son nom, son age ou son numéro de sécu.
Entreprise
private Hashtable ent;
remarque :
Les 4 méthodes chercher... renvoient le nombre de personne trouvé et place ces personnes dans une
collection. Cette collection (générique) implémentera la classe Hashtable.
Exercice : Ecrire le code de cette classe Entreprise. On utilisera les classes Personne ,NumSecu, Employe,
Cadre et Patron séjà écrite dans le chapitre VII.
System et Runtime
Les classes System et Runtime fournissent une interface à certaines fonctionnalités du système de façon
indépendante de la plate-forme.
...
char carLu = System.in.read();
System.out.println("caractère lu : " + carLu);
...
try{
Runtime.getRuntime().exec("notepad.exe") ;
}catch(IOException e){...}
...
...
System.exit(1);
...
La classe Calendar
Calendar dispose de champs moins précis que date : YEAR, MONTH, DAY, HOUR ect.. .
alors que Date va jusqu’à la milliseconde.
Calendar interprète une date suivant les règles imposées par un calendrier régional précis.
Une implémentation déjà fournie pour notre zone est GregorianCalendar qui est une sous
classe de Calendar.
On obtient une instance de Calendar par la méthode getInstance() :
La classe TimeZone
représente un fuseau horaire
contient une methode getDefault() qui récupère le fuseau horaire courant
contient une methode getTimeZone() qui permet de récupérer un fuseau horaire donné.
L’exemple du JDK1.2 est :
Object
Classe
Object Number
La classe Integer
Les méthodes de la classe Integer
Class EssaiInteger{
public static void main(java.lang.String[] args) {
int j=2; // équivalent à Integer j= new Integer(2);
String s ="15";
System.out.println(""+Integer.parseInt(s)+" "+"
"+Integer.toHexString(Integer.parseInt(s))+" "+ Integer.toBinaryString(Integer.parseInt(s)));
System.out.println(Integer.toString(3290));
// autre solution System.out.println(""+3290);
}
}
15 0000000F 0000.0000.0000.0000.0000.0000.0000.1111.
3290
La classe Double
Les méthodes de la classe Double
Un exemple
Class EssaiDouble{
public static void main(java.lang.String[] args) {
String s ="15.";
System.out.println(""+Double.parseDouble(s));
double x=Double.toString(34.9);
System.out.println(""+x); // appel à la méthode toString() de Double
x=x/0;
System.out.println("Aprés division par 0"+x); // affiche infinity
}
}
15.0
34.9
infinity
Les exceptions
Introduction
Jusqu'à présent la gestion des erreurs dans un programme se faisait directement dans le code
de la fonction par une gestion avec des if else. Cette gestion des erreurs rajoute des lignes de
code. Ainsi une méthode qui pourrait être codée sur quelques lignes, sans gestion d'erreurs
peut devenir importante quand on lui rajoute la gestion des erreurs. La gestion des erreurs
toujours été un problème pour les programmeurs. Cette gestion d'erreur si elle n'est prise en
compte dés l'analyse peut engendrer des cout de développement important. Cette gestion
d'erreur de plus complique le programme et donc la compréhension et la maintenance du
programme.
Au début des années 1990, C++ est le premier langage à mettre en place un traitement des
exceptions. Java a entièrement repris les mécanismes de gestion des erreurs de C++.
Le but de la gestion des exceptions est la séparation du code avec celui de la gestion des
erreurs.
La gestion des exception permet de créer un programme robuste, c'est à dire exempt le plus
possible d'arrêt brutal du programme.
import entreesortie.*;
class Essai1{
public static void main(String [] arg){
int [] tabInt= new int[5];
écriture en dehors des limites d'un tableau avec le message : uncaught exception
ArrayIndexoutOfBoundsException
import entreesortie.*;
class Essai2{
public static void main(String [] arg){
int [] tabInt= new int[5];
Le problème posé par cette solution est une augmentation des lignes de code et une
complication du programme.
De plus, si l'on oublie de tester une valeur, il y aura arrêt brutal du programme (bugs de
programmes).
import entreesortie.*;
Class Essai3{
public static void main(String [] arg){
int [] tabInt= new int[5];
try{
for(int i= 0;i<6;i++) System.out.println("tabInt["+i+"]="+tabInt[i]);
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println(e.toString());
}
try{
Le code à l'intérieur d'un bloc try peut lancer des exceptions. Ces exceptions peuvent être
interceptées dans le bloc qui suit le catch. Il peut y avoir plusieurs catch interceptant
différentes exceptions. En argument du catch on place le type d'exception que l'on veut
intercepter.
Une exception est une classe. et dans le code ci-dessus, le système passe en argument de catch
une référence sur un objet de la classe TypeException. On a donc accés aux méthodes de la
classe Exception. il suffit d'appeler e.methode().
si une exception apparait dans un bloc try, le code qui suit n'est pas exécuté. Seul est exécuté
le code dans le bloc catch.
Si la clause finally existe, quel que soit la configuration du programme, le bloc suivant finally
est exécuté.
Les Exceptions : des classes
Les exceptions sont des classes et donc peuvent bénéficier de l'héritage. Toutes les exceptions
héritent de la classe Throwable.
SecurityException (quand on essaye d’écrire sur le disque à partir d’une applet par exemple)
import entreesortie.*;
Class Essai3{
public static void main(String [] arg){
int [] tabInt= new int[5];
try{
for(int i= 0;i<6;i++) System.out.println("tabInt["+i+"]="+tabInt[i]);
}
catch(Exception e){
System.out.println(e.toString());
}
try{
tabInt[0]=0
tabInt[1]=0
tabInt[2]=0
tabInt[3]=0
tabInt[4]=0
java.lang.ArrayIndexOutOfBoundsException
Entrer nombre1 :
45
Entrer nombre2 :
0
java.lang.ArithmeticException
Remarque :
Il est possible de connaitre l'exception levée grace à l'opérateur insatnceof :
if(e instanceof ArrayIndexOutOfBoundsException)System.out.println("dépasement de
capacité du tableau");
package java.lang;
public
class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
public ArrayIndexOutOfBoundsException() {
super();
}
public ArrayIndexOutOfBoundsException(int index) {
super("Array index out of range: " + index);
}
public ArrayIndexOutOfBoundsException(String s) {
super(s);
}
}
un individu possède un nom en majuscule et habite dans un département dont le numéro est
compris entre 1 et 95.
La gestion des erreurs dans la classe setDepartement se faisait grace à un test sur la valeur unDept.
class Individu {
private String nom; // nom de l'individu
private byte departement; // département de résidence
Exemple :
method1 { (la flèche signifie : appel de )
call method2; methode1
}
method2 { methode2
call method3;
} methode3
method3 {
call readFile;
}
method1 {
errorCodeType error;
error = call method2;
if (error)
doErrorProcessing;
else
proceed;
}
errorCodeType method2 {
errorCodeType error;
error = call method3;
if (error)
return error;
else
proceed;
}
errorCodeType method3 {
errorCodeType error;
error = call readFile;
if (error)
return error;
else
proceed;
}
method1 {
try {
call method2;
} catch (exception) {
doErrorProcessing;
}
}
method2 throws exception {
call method3;
}
method3 throws exception {
call readFile;
}
Dans le code ci-dessus, il y a propagation de l'erreur qui apparaît dans la méthode3 et ceci
grace au mot clé throws jusqu'au traitement de cette erreur dans la méthode1 grace au code try
catch
Propager une exception
Les constructeurs font un appel direct à setDepartement. Une exception peut donc être levée
dans les constructeurs.
Signalons-le au compilateur :
L’exception n’est pas traitée ici, elle est seulement renvoyée au code appelant.
Capturer une exception
La méthode main suivante utilise le constructeur de la classe Individu, qui appelle
setDepartement.
Elle peut donc lever indirectement une exception.
Quand le gestionnaire d'exceptions entre dans un bloc catch, les catch suivants ne sont pas
examinés.
A chaque fois qu’on appelle setDepartement() dans une méthode, une exception est
susceptible d’être levée.
Il faut signaler cela au compilateur avec throws..., sinon ça compile pas.
Remarque : ici, on utilise throw d; pour indiquer que l’exception doit continuer à être
propagée dans la pile. La méthode mmm n’est pas apte à traiter complètement l’exception.
Pour relancer l’exception, la méthode doit être déclarer avec la clause throws.
Une hiérarchie d’exceptions
Les exceptions peuvent être organisées en hiérarchie, à travers un héritage.
IndividuException
DepartementException NomException
Dans ce cas, la clause catch(IndividuException e) capture les exceptions qui sont du type
IndividuException ou d’une sous-classe de IndividuException.
La clause finally
Lorsqu’un traitement doit être exécuté impérativement, qu’une exception soit levée ou non,
on le place dans un bloc introduit par finally.
try {
Individu p1 = new Individu(nom, dpt);
}
catch (IndividuException e) {
... // traitement de l’exception
}
finally {
[...fermer fichier...]
// Dans tous les cas, fermeture du fichier qui avait été ouvert
}
...
} // main
MereException
try {...}
catch ( Fille1Exception e ) {...} // ne traite que les exceptions Fille1
catch (MereException e) {...} // traite les Fille2, Fille3 et les meres.
public ListOfNumbers () {
victor = new Vector(size);
for (int i = 0; i < size; i++)
victor.addElement(new Integer(i));
}
public void writeList() {
PrintWriter out = new PrintWriter(new
FileWriter("OutFile.txt"));
out.close();
}
}
La solution :
try {
System.out.println("Entering try
statement");
out = new PrintWriter(
new FileWriter("OutFile.txt"));
Exercices
On désire changer la classe IntegerP (nouvelle version) qui prend en compte la gestion des
erreurs.
Ecrire cette nouvelle classe.
Un correction est donnée à la page suivante :
class NumberFormatException extends Exception {
public NumberFormatException () {
super();
}
public NumberFormatException (String s) {
super (s);
}
}
Class IntegerP{
public IntegerP(int value) {
this.value = value;
}
public IntegerP(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
System.out.println(""+IntegerP.parseInt(s)+" "+"
"+IntegerP.toHexString(IntegerP.parseInt(s))+" "+
Integer.toBinaryString(Integer.parseInt(s)));
System.out.println(IntegerP.toString(3290));
}
}
pb:java.lang.NumberFormatException: 1o
pb:java.lang.NumberFormatException: dépassement de capacité : 2147483648
pb:java.lang.NumberFormatException: radix 0en dehors des limites
56 00000038 111000
3290
Travail à faire :
1/ Faire l'étude des méthodes qui doivent lancer le gestionnaire d'exception.
2/ Implémenter et tester la nouvelle classe Point.
c/ On désire écrire la fonction copyValueOf qui permet de copier un tableau de caractères dans la
classe MaString :
public static MaString copyValueOf(char data[]) {
return copyValueOf(data, 0, data.length);
}
Ecrire la fonction MaString copyValueOf(char data[], int offset, int count) qui renvoie une
reference sur MaString. Cette méthode de tester les valeurs de offset et count et générer une
exception du type StringIndexOutOfBounsException
Reprendre cette méthode et la changer pour que celle-ci génère une exception du type
StringIndexOutOfBounsException.
Les autres méthodes ne changent pas. Expliquer
Exercices pratiques :
A–
NB : Créer un dossier qui porte votre nom sur le Bureau pour enregistrer tous les travaux de
cette épreuve
Soit un logiciel assurant la gestion des adhérents qui sont inscrits dans une
Médiathèque. Lorsqu'un adhérent est inscrit à la Médiathèque, on lui affecte automatiquement
un numéro et on fixe sa cotisation. La cotisation d’un adhérent peut changer en fonction de la
situation de l’adhérent. L’adhérent qui le souhaite peut ne plus appartenir à la Médiathèque, il
démissionne.
La classe Java ci-dessous permet d'instancier des objets Adhérent identifiés par un nom, un
numéro , (obtenu au fur et à mesure de la création des objets) et une cotisation et un état
(démissionné, ou actif).
}
Travail demandé :
1) Corriger les erreurs qui se sont glissées dans la classe Adhérent ci-dessus
6) Ajouter une méthode qui permet de trier le vecteur dans l'ordre croissant des noms
des adhérents.
Ecran de Recherche
- L'application de gestion d’un club de sports permet de gérer les adhérents qui s’inscrivent
pour pratiquer diverses disciplines (course, saut, lancé du poids, natation etc.…). Le club
possède des entraîneurs bénévoles.
• Toutes les disciplines sont définies par un nom, une description sommaire et l’âge
à partir duquel la discipline peut être pratiquée.
Travail à réaliser :
1) Ecrire une classe Adhérent et une classe Discipline, avec les constructeurs complets,
les données membres et une méthode d’affichage Affi_adherent() pour l’adhérent et
Affi_discipline() pour la discipline.
3) Développer dans la classe test le code permettant de saisir la liste des disciplines dans
un tableau Tdisp.
4) Dans la classe test, Ecrire une méthode Inscription() qui permet d’inscrire un
adhérent et le ranger dans un tableau.
5) Dans la classe test, Ecrire une méthode Afficheliste() qui permet d’afficher ce tableau.
6) Dans la classe test, Ecrire une méthode Trier() qui permet de trier ce tableau sur la
base du nom de l’adhérent.
Gestion club
Adhérent Diagramme de Classe
m_sNom:String
m_sPrenom:String
m_sAdresse :
String TEST
m_sage: Int
m_icode:Int Main()
Trier()
Saisie_adherent()
Inscription()
Affi_adherent()
Afficheliste()
Discipline
m_sNom:String
m_sdescrp:String
m_sageo:Int
Affi_discipline()
C–
Ajouter à cette classe un constructeur par défaut et un constructeur qui permet d’initialiser toutes les
propriétés. Créer toutes les méthodes set et get.
2) Un professeur est une personne avec les propriétés privées supplémentaires suivantes :
- Diplôme : text(20)
- Spécialité : text(20)
Développer la classe Professeur qui hérite de la classe personne. Ajouter les constructeurs adéquats.
4) Ecrire la méthode Affichage() qui permet d’afficher les informations d’une personne.
Surcharger cette méthode dans les classes Professeur et Eleve de façon à pouvoir afficher toutes
les informations respectives des deux classes.
6) Créer la classe de test afin de tester les méthodes d’affichage des classes Professeur et
Eleve
7) Ecrire le code permettant de saisir la liste des élèves dans un tableau (au clavier).
8) Développer le code permettant de trier ce tableau dans l’ordre croissant des noms des
élèves en utilisant une méthode de tri de votre choix. Annoncer le nom de la méthode
sous forme de commentaire.