Programmation Orientée Objet
Dr. Sana HAMDI
[email protected][email protected] 2
Sana Hamdi 06/12/2022
Les relations entre Classes
3
Sana Hamdi 06/12/2022
• Les relations entre classes
• La cohérence & le couplage
4
Sana Hamdi 06/12/2022
Les relations entre classe
5
Sana Hamdi 06/12/2022
Classe UML vs Classe java
Nom de la classe:
commence par une majuscule
+ notation CamelCase
public class CompteBancaire{
public String identifiant;
private float solde;
public Client titulaires [];
protected void debiter(float montant) {…}
protected void crediter(float montant) {…}
public float getSolde() {…}
}
- Private: accessible uniquement depuis sa propre classe
# Protected: accessible depuis sa propre classe et des classes qui héritent de cette classe
+ Public: accessible de partout
Attribut statique : description soulignée
6
Sana Hamdi 06/12/2022
Interface UML vs interface java
public interface ObjectGeometrique{
public float calculerAir();
}
7
Sana Hamdi 06/12/2022
Relations entre classes et interfaces
Plusieurs types de relations
▫ Association
Agrégation
Composition
▫ Héritage
▫ Implémentation
Navigation: Représenté par une flèche sur le bout d’une
relation de type Association
▫ Signifie qu’une classe peut accéder aux attributs et opérations d’une autre classe
(unidirectionnelle).
▫ Si aucune flèche, la relation est navigable dans les deux sens (bidirectionnelle).
8
Sana Hamdi 06/12/2022
Association unidirectionnelle:
class Cercle{
Point centre;
double rayon;
Cercle(int x, int y, double r){
this.centre = new Point (x, y);
rayon = r;
}
}
La classe Point ne connaît pas l'existence de la classe class Point{
Cercle (unidirectionnelle). int x;
Un point peut être partagé (à un même moment il
int y;
peut être lié à plusieurs instances d'objets
(éventuellement d'autres classes). Point(int x, int y){
Or, on voulait que Le Point représentant le centre this.x = x;
n’est pas partagé (à un même moment, une this.y = y;
instance de Point ne peut être lié qu'à un seul }
Cercle) }
9
Sana Hamdi 06/12/2022
Associations bidirectionnelle: Exemple 1
0..1 0..1
10
Sana Hamdi 06/12/2022
Exemple 1
public class person {
telephone outil;
String nom;
person(String nom){
this.nom = nom;
}
public void addOutil(telephone outil) {
if( outil != null ){
if (outil.getPropri() !=null ){ //si outil est déjà connecté à une autre Person
outil.getPropri().setOutil(null); // cette autre Person doit se déconnecter
}
this.setOutil(outil);
outil.setPropri(this );
}
}
public telephone getOutil() {
return( outil );
}
public void setOutil( telephone outil ) {
this.outil=outil;
}
}
11
Sana Hamdi 06/12/2022
Exemple 1
public class telephone {
person propri;
String marque;
telephone (String s){
marque =s;
}
public void addPropri( person propri ) {
if( propri != null ) {
if (propri.getOutil() != null){//si proprio est déjà connecté à un autre telephone
propri.getOutil().setPropri( null ); // cet autre telephone doit se déconnecter
}
this.setPropri( propri );
propri.setOutil( this );
}
}
public void setPropri(person propri){ this.propri=propri; }
public person getPropri(){ return(propri); }
}
12
Sana Hamdi 06/12/2022
Exemple 1
public class test{
public static void main (String [] args) {
telephone t = new telephone("nokia");
person p = new person("Salah");
t.addPropri(p);
person p2 = new person("Iyed");
p2.addOutil(t); // t est de Iyed
p.addOutil(t); // t devient de Salah
if (p2.getOutil() == t)
System.out.println("t est le téléphone de Iyed");
if (p.getOutil() == t)
System.out.println("t est le téléphone de Salah");
System.out.println(p2.getOutil().marque); //renvoie une exception car p2.outil est null
} // p2 (Iyed n’a plus de téléphone)
}
13
Sana Hamdi 06/12/2022
Associations bidirectionnelle: Exemple2
• Les valeurs de multiplicité « 0..1 » indiquent qu’une personne a au
minimum zéro compte et au maximum 1 compte. C’est à dire « Une
personne a un compte ou aucun ».
• Les valeurs de multiplicité « 1 » signifient qu’un compte appartient a une
personne et une seule. On peut aussi écrire « 1..1 ».
14
Sana Hamdi 06/12/2022
Exemple 2
public class Personne { void CréerCompte(int n) {
cpt = new Compte(n,this);
String nom; cpt.setprop(this);
String prenom; }
float revenu; void afficher(){
Compte cpt;
Personne(String n,String p,float r){ }
nom = n; Compte getCompte(){
prenom = p; return cpt;
revenu = r; }
} }
15
Sana Hamdi 06/12/2022
Exemple 2
void créditer(float s){
public class Compte { solde+=s;
int numero; }
float solde; void débiter(float s){
Personne proprietaire; solde-=s;
Compte(int num, Personne propri){ }
numero = num; void afficher(){
solde = 0;
if (propri!=null) { }
void setprop (Personne p) {
if (propri.getCompte() != null) { proprietaire = p;
//si proprio est déjà connecté à un autre compte }
Personne getprop () {
propri.getCompte().setprop(null); return proprietaire ;
// cet autre compte doit se déconnecter }
} void fermerCompte(){
setprop (propri); // this.finalize();
} }
}
}
16
Sana Hamdi 06/12/2022
Exemple 2
public class Main {
public static void main (String [] args) {
Personne p = new Personne("med", "salah", 1500);
p.CréerCompte(1000);
Compte c= p.cpt; // p est le proprietaire du compte c
System.out.println(c.getprop().nom); //Affiche med
Compte c1 = new Compte(2000, p);//p devient le proprietaire du c1
System.out.println(c1.getprop().nom); //Affiche med
System.out.println(c.getprop().nom); //erreur car c n'a pas de
//proprietaire (null)
}
}
17
Sana Hamdi 06/12/2022
Exemple 2: Associations 0..n – 1..1
Et si une personne pouvait avoir class Personne{
plusieurs comptes? String nom;
String prenom;
float revenu;
Dans la classe personne, on n'aurait plus
ArrayList<Compte> comptes = new
une seule référence d'un compte, mais un
ArrayList<Compte>();
ensemble de références vers des objets
Personne(String n,String p,float r){
comptes :
nom = n;
prenom = p;
• Soit sous la forme d'un tableau (si le
revenu = r;
nombre de compte est fixé dès le départ)
}
void AjouterCompte(Compte) {
• Soit sous la forme d'une collection
Comptes.add(c)}
(ArrayList), qui est un type de tableau
void afficher(){…}
particulier dont la taille peut varier.
}
18
Sana Hamdi 06/12/2022
Exercice
À partir des classes représentées au format UML, écrire le
code en java.
19
Sana Hamdi 06/12/2022
Exercice (suite)
public class Crayon {
private char type;
private String couleur;
public Crayon (char leType , String laCouleur) {
this.type = leType;
this.couleur = laCouleur;
}
public char getType() {
return this.type;
}
public String toString() {
return "Type:"+this.type+" Couleur:"+this.couleur;
}
}
20
Sana Hamdi 06/12/2022
Exercice (suite)
public class Etudiant {
private String nom;
private String prenom;
// Constructeur
public Etudiant (String unNom , String unPrenom){
this.nom = unNom;
this.prenom = unPrenom;
}
// toString
public String toString(){
return this.prenom+" "+this.nom;
}
}
21
Sana Hamdi 06/12/2022
Exercice (suite)
class Test{
public static void main(String args[]){
Crayon c1 = new Crayon('F' , "Bleu");
System.out.println(c1.toString());
Etudiant e1 = new Etudiant("Friedman", "Milton");
System.out.println(e1.toString());
}
}
22
Sana Hamdi 06/12/2022
Exercice (suite)
• Les 2 classes sont indépendantes. Il existe des crayons; il existe des
étudiants mais les étudiants sont indépendants des crayons.
• Nous allons faire évoluer notre cas pour dire qu’un étudiant possède
un crayon.
23
Sana Hamdi 06/12/2022
Exercice (suite)
public class Etudiant {
private String nom;
private String prenom;
Comment faire en Java ? private Crayon leCrayon;
//…
}
• Comment se servir de cet attribut supplémentaire ?
• Lorsque l’étudiant est créé, il ne possède aucun crayon.
• Comment donner un crayon à l’étudiant (il faut que le crayon
existe) ?
• Il faut ajouter une méthode qui valorise (donne une valeur) la
propriété privée leCrayon de l’étudiant. Ce sera donc une
méthode de la classe Etudiant. Appelons là «ajouteCrayon»
24
Sana Hamdi 06/12/2022
Exercice (suite)
public class Etudiant {
private String nom;
private String prenom;
private Crayon leCrayon;
public Etudiant (String unNom , String unPrenom){
this.nom = unNom;
this.prenom = unPrenom;
}
public String toString(){
return this.prenom+" "+this.nom;
}
// Méthode qui ajoute un crayon à un étudiant
public void ajouteCrayon(Crayon unCrayon){
this.leCrayon = unCrayon;
}
}
25
Sana Hamdi 06/12/2022
Exercice (suite)
• Si l’étudiant perd son crayon, il ne possède plus de
crayon. Il faut donc affecter la valeur NULL à la
propriété « leCrayon » de l’étudiant.
• Il faut ajouter une méthode « perdCrayon » dans la
classe « Etudiant ».
26
Sana Hamdi 06/12/2022
Exercice (suite)
public class Etudiant {
private String nom;
private String prenom;
private Crayon leCrayon;
public Etudiant (String unNom , String unPrenom){
this.nom = unNom;
this.prenom = unPrenom;
}
public String toString(){ // Méthode toString pour un meilleur affichage
String message =this.prenom+" "+this.nom;
if (leCrayon !=null)
message=message+" possède le crayon "+leCrayon.toString();
else
message+=" ne possède pas de crayon";
return message;
}
public void ajouteCrayon(Crayon unCrayon){
this.leCrayon = unCrayon;
}
// Méthode qui retire un crayon de l’étudiant
public void perdCrayon(){
this.leCrayon = null;
}
}
27
Sana Hamdi 06/12/2022
Exercice (suite)
• Un étudiant a en général plusieurs crayons
• Nous allons donc attribuer une collections de crayons
dans la classe « Etudiant »
• Il faut donc modifier le constructeur «Etudiant»
• Il faut aussi modifier les méthodes «ajouteCrayon» et
«perdCrayon»
• La méthode « toString » est adaptée à cette nouvelle
sorte d’étudiant.
• Une méthode privée qui nous donne le nombre de
crayons de l’étudiant peut aussi être ajoutée.
28
Sana Hamdi 06/12/2022
Exercice (suite)
public class Etudiant {
private String nom;
private String prenom;
private ArrayList trousse;
public Etudiant (String unNom , String unPrenom){ //Constructeur
this.nom = unNom;
this.prenom = unPrenom;
this.trousse = new ArrayList();}
private int nbCrayons(){
return this.trousse.size();}
public String toString(){ //toString
String message =this.prenom+" "+this.nom;
message+=nbCrayons()+" crayons.";
for (int i=0; i<nbCrayons();i++){
message+="\n\t"+((Crayon)(trousse.get(i))).toString();
}
return message;}
public void ajouteCrayon(Crayon unCrayon){//Ajouter un crayon à la trousse
this.trousse.add(unCrayon);}
public void perdCrayon(Crayon unCrayon){
this.trousse.remove(unCrayon);}
}
29
Sana Hamdi 06/12/2022
Exercice (suite)
public static void main(String args[]){
Crayon c1 = new Crayon('F' , "Bleu");
System.out.println(c1.toString());
Etudiant e1 = new Etudiant("Friedman", "Milton");
System.out.println(e1.toString());
// Ajoute à l'étudiant e1 le crayon c1
e1.ajouteCrayon(c1);
System.out.println(e1.toString());
// Second crayon
e1.ajouteCrayon(new Crayon('B',"Rouge"));
System.out.println(e1.toString());
// Il perd le premier crayon
e1.perdCrayon(c1);
System.out.println(e1.toString());
}
30
Sana Hamdi 06/12/2022
Association d'une classe sur elle même
public class Personne{
private String nom;
private Personne epoux = null;
private boolean marie = false;
public Personne(String nom){
this.nom = nom;
}
public void semarieà(Personne p){
epoux = p;
marie = true;
//...
}
public boolean marie(){
return marie;
}
//...
}
31
Sana Hamdi 06/12/2022
Agrégation
• Les critères suivants impliquent une agrégation:
o une classe fait partie d’une autre classe;
o une partie peut exister indépendamment du tout
Tout Partie
Une agrégation
A B
o Les agrégations peuvent s'implémenter comme les
associations.
32
Sana Hamdi 06/12/2022
Agrégation
class Entreprise {
class Service {
Service S;
Entrprise E;
Service getService() {
Entrprise getEntrprise(){
return S;
return E;
}
}
void setService(Service S){
void setEntreprise(Entrprise E){
this.S = S;
this.E = E;
S.setEntreprise(this);
}
}
}
}
33
Sana Hamdi 06/12/2022
Agrégation
public static void main(String args[]){
Entrprise e = new Entrprise ();
Service s = new Service();
e.SetService(s);
System.out.println(s.getEntrprise);
//Le résultat doit être e
}
}
34
Sana Hamdi 06/12/2022
Agrégation 0..n – 0..n
public class ListeDeClients{
ArrayList<Personne> laListe;
ListeDeClients(){
laListe = new ArrayList<Personne>();
}
void inclus (Personne p){
laListe.add(p);
// Donc p.EstClient(this) va envoyer true
}
public Vector<Personne> getlaListe(){
return laListe; }
}
35
Sana Hamdi 06/12/2022
Agrégation 0..n – 0..n
public class Personne{
private String nom;
public Personne( String nom ){
this.nom=nom;
}
public boolean EstClient(ListeDeClients l){
return (l.laListe()).contains(this );
}
}
36
Sana Hamdi 06/12/2022
Composition
Composite Composant
• La composition est un cas particulier de
l’agrégation
• Ils sont physiquement contenus dans l’agrégat.
37
Sana Hamdi 06/12/2022
Composition
Voiture Moteur
1 1
public class Voiture{ public class Moteur{
private Moteur moteur;
public Voiture(){ private Voiture v;
moteur = new Moteur(this); Moteur (Voiture v){
} this.v=v;
}
}
38
Sana Hamdi 06/12/2022
Composition
public static void main(String args[]){
Moteur m = new Moteur();
for(int i=0; i< 8 ;i++){
System.out.println(m.lesCylindres[i].getMoteur);
//Le résultat doit être m pour chaque cylindre
}
}
39
Sana Hamdi 06/12/2022
La cohérence et le couplage
40
Sana Hamdi 06/12/2022
Cohérence vs incohérence
• Un objet est cohérent si ses méthodes et ses
traitements forment un tout.
• Donc un objet est incohérent s’il est composé de
plusieurs parties indépendantes
41
Sana Hamdi 06/12/2022
Incohérence et classe
• Une classe est incohérente si on peut la découper
en plusieurs classes indépendantes.
3
2
1
42
Sana Hamdi 06/12/2022
Découper une classe
• On peut découper une classe si elle est composée
de parties (attributs et méthodes) indépendantes.
43
Sana Hamdi 06/12/2022
Découper une classe
44
Sana Hamdi 06/12/2022
LCOM (Lack of Cohesion Method)
• Cette métrique est définie par « Chidamber » et
« Kemerer » et permet de mesurer le niveau de
cohérence d’une classe.
• Algorithme:
45
Sana Hamdi 06/12/2022
Exemple de LCOM
• Trois paires: {m1, m2}, {m1, m3} et {m2, m3}
• P=2 et Q=1
• P - Q = 1, donc il faut couper la classe!
a1 a2 a3 a4
m1 m2 m3
46
Sana Hamdi 06/12/2022
Couplage et classe/interface
Une classe/interface est couplée à une autre, si
elle a besoin d’elle pour être compilée.
▫ Appel de méthodes.
▫ Typage de propriétés.
▫ Héritage.
▫ Implémentation.
47
Sana Hamdi 06/12/2022
Couplé vs isolé
48
Sana Hamdi 06/12/2022
Trop couplé ou mal couplé
Un objet couplé à beaucoup d’objets Une chaîne: Plus elle est grande,
Objet trop couplé plus c’est difficile de tester un objet
Objets mal couplés
49
Sana Hamdi 06/12/2022
Métriques de couplage (1)
• Plusieurs métriques sont définies par
«Chidamber» et «Kemerer» permettant de
mesurer le degré de couplage d’une classe.
• L’objectif est de déterminer les classes mal et
trop couplés.
50
Sana Hamdi 06/12/2022
Métriques de couplage (2)
• DIT (Depth of Inheretance Tree)
Mesurer la profondeur de l’arbre de l’héritage
• NOC (Number Of Children)
À l’inverse mesurer le nombre de classes filles
• CBO (Coupling Between Objects)
Mesurer le nombre de voisins en relation de couplage
• RFC (Request For a Class)
Mesurer la taille de la chaine (cycle)
51
Sana Hamdi 06/12/2022
Couplage fort vs Couplage faible
• Couplage fort:
- Un objet fortement couplé est un objet qui a
besoin de connaître les autres objets et est
généralement très dépendant les uns des autres.
- La modification d’un objet dans une application
fortement couplée nécessite souvent de modifier
d’autres objets.
52
Sana Hamdi 06/12/2022
Couplage fort vs Couplage faible
• Couplage faible:
-Le couplage faible permet de réduire les
interdépendances entre les composants d’un
système dans le but de réduire le risque que les
changements dans un composant nécessitent des
changements dans tout autre composant.
-Le couplage faible est un concept destiné à
augmenter la flexibilité du système, à le rendre
plus maintenable et à rendre l’ensemble du
framework plus stable.
53
Sana Hamdi 06/12/2022
class Moteur {
public int puissance = 0;
public int getPuissance() {
return puissance;
}
public void setPuissance(int p) {
puissance = p;
}}
public class Voiture {
public static void main(String[] args) {
Moteur obj = new Moteur();
obj.puissance = 255; //cela provoque un couplage fort.
System.out.println("La puissance du moteur est : " + obj.puissance);
}}
Merci pour votre attention !
Dr. Sana Hamdi
Maitre Assistante en Informatique à l’INSAT
Membre du Laboratoire LIPAH (FST-Tunisie)
et du Laboratoire SAMOVAR (Telecom SudParis-France)