2. UML et langages objets
•
La plupart des langages sont orientés objet
Les concepts objets principaux sont toujours
présents (encapsulation, héritage..)
•
Certaines notions avancées sont survolées ou
oubliées (agrégation, héritage multiple,
polymorphisme, interface..)
•
mercredi 23 octobre 13
•
Tous les langages OO sont égaux, mais certains
sont plus égaux que d’autres...
3. Usages d’écriture en Java
•
•
•
Quelques règles à suivre
•
•
•
UneClasse
UNECONSTANTE (on tolère UNE_CONSTANTE)
autreChoseQuUneClasse
Notation Hongroise
•
•
maMethodeAMoi
plutôt que ma_methode_a_moi
Pas d’accent, ni d’espace dans les noms
mercredi 23 octobre 13
4. Définition d’une classe
•
•
Rappel : une classe est un modèle
En Java, tout est encapsulé dans des classes
public class UneClasse
{
}
•
mercredi 23 octobre 13
Un fichier = une classe, et une classe par fichier
•
Nom du fichier = nom de la classe !
•
Casse comprise !
5. Une classe en Java
•
Toutes les classes en Java héritent
implicitement de la classe Object
•
•
Utilisent les classes du package java.lang
Et implémentent un constructeur par défaut
sans paramètre
import java.lang.*;
public class UneClasse extends Object
{
public UneClasse()
{
super();
}
}
mercredi 23 octobre 13
6. Classes et objets
•
Les objets sont les instances de classe
Facture f; // création variable
f=new Facture(); // instanciation, et affectation
•
Version condensée :
Facture f=new Facture(); // création,
instanciation, et affectation
mercredi 23 octobre 13
7. Attributs et méthodes
•
Les classes seront constituées des attributs et
méthodes
public class Facture
{
double prixHT; // attributs
double tva;
double getPrixTTC() // méthode
{
return prixHT*(tva/100+1);
}
}
mercredi 23 octobre 13
Facture
prixHT
tva
getPrixTTC()
8. Utilisation d’une instance
public static void main(String[] args)
{
Facture f=new Facture();
f.prixHT=120;
f.tva=19.6;
Syntaxe
instance.attribut double result=f.getPrixTTC();
}
Syntaxe
instance.méthode()
mercredi 23 octobre 13
9. •
La
méthode est
publique, elle
constitue
mercredi 23 octobre 13
Encapsulation
L’encapsulation dans un objet (la “boîte
noire”) est définie en Java par les mots clés
de visibilité
L’attribut est ici
public class Vehicule
privé, il fait partie de
{
l’implémentation
private int vitesse;
public void setVitesse(int newvitesse)
{
if(newvitesse>=0)
vitesse=newvitesse;
}
}
10. Getters et Setters
•
La visibilité des attributs se fait via des
accesseurs : GET et SET
private int prix;
public int getPrix()
{
return prix;
}
public void setPrix(int newprix)
{
prix=newprix;
}
mercredi 23 octobre 13
17. Naissance d’un objet
Client c;
c=new Client();
Instance
Constructeur
c
mercredi 23 octobre 13
Pointe vers
une instance
en mémoire
18. Mort d’un objet
Garbage Collector
Instance
c ne pointe
plus
sur l’instance
X
c=null;
ou
c=new Client(); // autre instance
mercredi 23 octobre 13
c
19. Construction
•
Le constructeur est appelé lors de
l’instanciation d’un objet
•
Il permet d’initialiser l’instance pour qu’elle
soit “propre” dès le début
•
Si pas de constructeur : constructeur
implicite sans paramètre
•
Si constructeur : le constructeur implicite
n’existe plus
•
Il est possible de surcharger le constructeur
mercredi 23 octobre 13
20. Le constructeur
•
•
Nom de la méthode = nom de la classe
Aucun paramètre de sortie (même pas void)
public class Client
{
private String nom;
public Client() // constructeur
{
}
Client c=new Client();
Client c=new Client(“Bob”);
}
public Client(String newnom) // surcharge constructeur
{
nom=newnom;
}
mercredi 23 octobre 13
21. Quelques règles à suivre
•
Une interface doit être simplifiée au
maximum et adaptée aux besoin de
l’utilisateur
•
•
L’interface doit être documentée
L’instance doit en permanence être
cohérente en mémoire
•
•
mercredi 23 octobre 13
Initialisation propre via les constructeurs
Protection des données via les setters
22. Le mot clé this
•
•
mercredi 23 octobre 13
Représente l’instance en cours
Utilisé à l’intérieur même de la classe
23. this pour lever une
ambiguité
Il est conseillé d’utiliser this
systématiquement pour lever tout
ambiguité
public class Client
{
private String nom;
public Client(String nom)
{
this.nom=nom;
}
Le paramètre
}
d’entrée
L’attribut
mercredi 23 octobre 13
24. this pour appeler un
constructeur
public class Client
{
private String nom;
public Client() // constructeur
{
this(“Nom par défaut”);
}
}
public Client(String nom) // surcharge du constructeur
{
this.nom=nom;
Client c1=new Client();
}
mercredi 23 octobre 13
Client c2=new Client(“Bob”);
25. this pour appeler un
constructeur
public class Client
{
private String nom;
public Client() // constructeur
{
this(“Nom par défaut”);
}
X
N’écrire qu’un constr
avec param permet
d’interdire la construction
public Client(String nom) // surcharge du constructeur paramètre
sans
{
}
}
this.nom=nom;
mercredi 23 octobre 13
X
Client c1=new Client();
Client c2=new Client(“Bob”);
26. this pour envoyer
l’instance a une autre
méthode
public uneMethode()
{
uneInstance.uneAutreMethode(this);
}
mercredi 23 octobre 13
27. Exemple de rétro-appel
avec this
public class Voiture
{
public class Carrossier
public Aile aileDroite;
{
public void peindre(Voiture v,String coul) public Capot capot;
...
{
public void ordonneCarrossier()
v.aileDroite=coul;
{
v.capot=coul;
Carrossier c=new Carrossier();
...
Cette liaison est
c.peindre(this,”rouge”);
}
une association
}
}
}
Le carrossier agira
sur moi-même
mercredi 23 octobre 13
28. L’association
•
•
Liaison simple entre deux classes
Ex : un client utilise un TPE (terminal de paiement)
L’instance de
l’élément associé vient de
l’extérieur
public class Client
{
void paiement(Tpe terminal)
{
...
terminal.saisieCode(“1234”);
...
}
}
mercredi 23 octobre 13
29. •
•
L’agrégation
Liaison plus “intime” entre deux classes
Ex : on intègre un moteur à une voiture
public class Voiture
L’élément agrégé
{
est un attribut
private Moteur moteur;
public Voiture(Moteur m)
{
L’instance de
l’élément agrégé vient de
this.moteur=m;
l’extérieur
}
Moteur m=new Moteur();
}
Voiture v=new Voiture(m);
...
v=null; // on tue l’instance de voiture,
// mais le moteur m existe toujours
mercredi 23 octobre 13
30. •
•
La composition
Forme forte de l’agrégation
Ex : un humain est composé d’une tête
public class Humain
L’élément composé
{
est un attribut
private Tete t;
public Humain() // constructeur
{
this.t=new Tete();
Humain h=new Humain();
}
...
L’instance est
}
h=null; // on tue l’instance de humain,
construite à
l’intérieur de
l’objet
mercredi 23 octobre 13
// ainsi qu’implicitement sa tête
35. Agrégation vs Composition
L’instance
de moteur reste “en
vie”
Voiture
Moteur
X
Moteur mot
X
X
Humain
X
X
v
Tete tete
m
X
X
h
mercredi 23 octobre 13
X
Tete
La tête
“meurt”
avec
l’instance
composée
36. Association (ou agrégation)
bidirectionnelle
•
Une association peut être mentionnée des
deux côtés
•
•
Cela reste optionnel
Réfléchir à l’utilité d’une telle liaison
public class Voiture
{
private Personne conducteur;
}
mercredi 23 octobre 13
public class Personne
{
private Voiture maVoiture;
}
37. Cardinalités multiples
•
Lorsque la liaison est de type 0..N ou 1..N, on
va stocker les instances dans un tableau ou
une liste chainée
public class Voiture
{
// nombre d’éléments fixes
private Roue[] roues;
}
public class Livre
{
private ArrayList<Page> pages;
}
mercredi 23 octobre 13
public class Page
{
// souvent peu utile
private Livre monLivre;
}
38. Classes d’association
•
•
En UML, c’est une classe à part
En pratique, c’est une classe comme les autres, contenant :
•
•
Les attributs de la classe d’association
Les informations permettant d’intégrer la notion
d’association :
•
•
•
mercredi 23 octobre 13
Tuple formé des pointeurs vers les 2 (ou plus) classes
associées
Rarement des méthodes
Mieux vaut remplacer par une classe à part entière dès l’analyse
39. Implémentation d’une
classe d’association
public class Vol
{
...
}
mercredi 23 octobre 13
public class InfosEscales
{
private Vol vol;
private Aeroport aeroport;
private Time heureDepart;
private Time heureArrivee;
}
public class Aeroport
{
...
}
40. L’héritage
•
Conceptuellement : hiérarchisation de thèmes
voisins (ex :Véhicule / Voiture / Break)
•
Pragmatiquement : possibilité de regrouper du
code commun à différentes classes
mercredi 23 octobre 13
41. L’héritage en tant que
généralisation
•
Permet de factoriser du code
Vehicule
Généralisation
Voiture
public class Voiture
{
private Moteur m;
}
mercredi 23 octobre 13
Moto
public class Moto
{
private Moteur m;
}
42. L’héritage en tant que
généralisation
•
Permet de factoriser du code
Vehicule
Généralisation
Voiture
public class Voiture
{
private Moteur m;
}
mercredi 23 octobre 13
Moto
public class Moto
{
private Moteur m;
}
public class Vehicule
{
protected Moteur m;
}
public class Voiture extends Vehicule
{
...
}
43. •
L’héritage en tant que
spécialisation
Permet de reprendre une classe en la
modifiant
public class Fenetre
{
...
}
Fenetre
Spécialisation
BoiteDialogue
mercredi 23 octobre 13
public class BoiteDialogue extends Fenetre
{
...
}
44. Mot-clé super
•
•
S’utilise comme this
•
Usages :
mercredi 23 octobre 13
Représente non pas sa propre instance, mais
l’instance de la classe mère
•
•
•
Appeler un constructeur de la classe mère
Appeler une méthode de la classe mère
Lever une ambiguité sur des méthodes de
mêmes noms dans la classe mère/fille
45. •
Appel constructeur
classe mère de sa classe
Attention, on n’hérite pas du constructeur
mère !
public class Livre extends Produit
public class Produit
{
{
protected int nbpages;
protected int ref;
public Livre(int ref,int nbpages)
public Produit(int ref)
{
{
super(ref);
this.ref=ref;
this.nbpages=nbpages;
Appel
}
constructeur classe }
}
}
mère
L’appel au constructeur de la classe
mère est impérativement la
première instruction du
constructeur
mercredi 23 octobre 13
46. Constructeurs et
héritage
•
Quelques règles à comprendre :
•
•
Pas d’héritage des constructeurs
Il est impératif d’appeler le constructeur de
la classe mère
•
•
mercredi 23 octobre 13
En cascade jusqu’à Object()
Si l’on ne le fait pas, Java effectue un appel
implicite de type super()
47. Exemple posant problème
public class Mere
{
public Mere(int i)
{
...
}
}
•
Pas d’appel au constructeur parent dans Fille
•
•
mercredi 23 octobre 13
public class Fille extends Mere
{
public Fille(int i)
{
...
}
}
Du coup, Java tente d’en faire un implicite
•
super()
Mais il n’y a pas de constructeur sans
paramètre dans Mere -> erreur
•
Il faut insérer un super(i) dans Fille
48. Exemple un peu tordu
public class Mere
{
public Mere(int i)
{
...
}
public Mere()
{
...
}
}
•
•
public class Fille extends Mere
{
// pas de constructeur
}
Fille f=new Fille(); est autorisé
Fille f=new Fille(12); est interdit !
Pas de constructeur = Constructeur
implicite sans paramètre
•
Ce constructeur fait un appel implicite
à super()
•
mercredi 23 octobre 13
•
Le constructeur Mere() est donc
appelé
49. •
Surcharge de méthodes
Permet de réécrire une méthode de la
classe mère dans une classe fille
•
•
Utile lors de la spécialisation d’une
classe
C’est également la base du
polymorphisme
public class Voiture
{
...
public void ouvrePorteCoffre()
{ ... }
}
mercredi 23 octobre 13
public class Break extends Voiture
{
...
public void ouvrePorteCoffre()
{
...
// éventuellement appel a
méthode mère
super.ouvrePorteCoffre();
...
}
}
50. Masquage d’attributs
•
Permet de réécrire un attribut de la classe
mère dans une classe fille
•
Sert essentiellement pour redéfinir les
initialisations
•
On ne peut changer le type
public class Voiture
{
private int vitesseMax=160;
}
mercredi 23 octobre 13
public class VoitureSport extends
Voiture
{
private int vitesseMax=250;
}
51. Redéfinition de
méthodes
•
•
N’est pas lié à l’héritage
Permet la réécriture de méthodes public class ObjetGraphique
dans une même classes
{
public void setColor(String col)
Avec un nombre d’attributs
{ ... }
différents
public void setColor(int numcol)
{ ... }
ou des attributs de nature
public void setColor(int r,int v,int b)
différentes
{ ... }
Utile pour fournir une interface de }
classe s’adaptant aux besoins de
l’utilisateur
•
•
•
mercredi 23 octobre 13
52. Polymorphisme
•
Permet un traitement qui va s’adapter au
contexte
•
Dans la pratique : une méthode surchargée
via une structure d’héritage
public class Forme
{
public double calculeAire() { ... }
}
public class Cercle extends Forme
{
public double calculeAire() { ... }
}
mercredi 23 octobre 13
public class Rectangle extends Forme
{
public double calculeAire() { ... }
}
53. •
Utilisation du
polymorphisme
Permet d’uniformiser des traitements
hétérogènes
AVANT :
{
// cumul aire
double aire=0;
for(...)
{
Forme formeCourante=...;
if(formeCourante==cercle)
aire=aire+formeCourante.calculeAireCercle();
if(formeCourante==rectangle)
aire=aire+formeCourante.calculeAireRectangle();
}
}
mercredi 23 octobre 13
APRES :
{
// cumul aire
double aire=0;
for(...)
{
Forme formeCourante=...;
aire=aire+formeCourante.calculeAire();
}
}
54. Downcasting
•
Transtypage permettant de considérer une
instance “comme si” elle était de sa classe
mère
•
Facilite les traitements polymorphe
{
}
mercredi 23 octobre 13
Cercle c=new Cercle();
...
Forme f=(Forme)c; // downcasting
Forme f2=new Cercle(); // downcast dès l’instanciation
55. Upcasting
•
Transtypage permettant de “préciser” le type
d’une instance
•
Parfois risqué (risque de plantage à
l’exécution)
{
}
mercredi 23 octobre 13
Produit p=liste.get(i);
...
Livre l=(Livre)p; // upcasting
int nb=l.getNbPages();
56. Méthode abstraite
•
Dans l’implémentation du polymorphisme, la
méthode “mère” n’a souvent pas de sens
•
Ex : on ne peut pas calculer “comme ça”
l’aire d’une forme géométrique
•
•
mercredi 23 octobre 13
Mais toutes les formes ont leur aire
calculable
On utilise la notion de méthode abstraite
57. Mise en place méthode
Avant :
abstraite
public class Forme
{
public double calculeAire()
{
return 0;
}
}
•
public abstract class Forme
{
public abstract double calculeAire();
}
Si méthode abstraite :
•
•
•
Après :
mercredi 23 octobre 13
classe abstraite
•
on ne peut l’instancier Forme f=new Forme();
obligation d’implémentation de la méthode dans les
classes filles
Une méthode abstraite fait partie de l’interface
58. Intérêts du polymorphisme
avec abstract
•
Empêche l’instanciation de la classe mère qui de
toute manière ne représente rien concrétement
•
•
une instance de “Forme”, sans autre détail, ne
pourrait être exploitée
Oblige le développeur a implémenter la méthode
polymorphe dans toutes les classes filles
•
mercredi 23 octobre 13
Empêche les incohérences dans le cas d’une
écriture de nouvelles classes filles
59. L’héritage multiple
•
•
En résumé :
•
Version plus détaillée :
•
•
mercredi 23 octobre 13
Il n’y a pas d’héritage multiple en Java
Pas d’héritage d’implémentation
•
la factorisation de code multiple peut
poser des problèmes d’ambiguités
Mais un héritage d’interface
•
Permet d’étendre le polymorphisme
60. Comment représenter
l’héritage d’interface
•
•
•
•
mercredi 23 octobre 13
Notion d’interface explicitée
Permet de faire un héritage sans aucune
implémentation
•
Equivalent des “classes virtuelles pures” en C++
Fonctionne comme une classe abstraite qui ne
contiendrait que des méthodes abstraites
Permet un héritage multiple
•
Peut être cumulé à un héritage d’implémentation
61. Comprendre la notion
d’interface
•
•
•
mercredi 23 octobre 13
Forme faible d’héritage
Expurgée de notion d’extension
On parle plutôt d’affectation de capacités
•
D’où le suffixe “-able” : a la capacité de...
62. Exemple d’interface
public interface Colorable
{
public void setColor(String nomcol);
}
Pas besoin
de préciser
“abstract”
public class Forme
implements Colorable
{
Représente
public void setColor(String nomcol) { ... }
l’héritage d’interface}
Implémentation de
l’interface
mercredi 23 octobre 13
63. Cumul interface/héritage
classique
•
•
On peut cumuler au sein d’une même classe
•
•
Un héritage d’implémentation (extends...)
Un ou plusieurs héritages d’interface
(implements...)
Ex :
public class Voiture
implements Colorable, Crashable,
extends Vehicule
mercredi 23 octobre 13
64. Utilisation d’une
interface
•
Traitements polymorphes comme avec une
méthode abstraite
public void paintItBlack(ArrayList<Colorable> liste)
{
for(int i=0;i<liste.size();i++)
{
Colorable elem=liste.get(i);
elem.setColor(“noir”);
}
}
mercredi 23 octobre 13
65. •
•
Hétérogénéité possible
d’une créer un “dénominateur
interface
L’interface permet de
commun” a des éléments très divers
Permet de faire des traitements polymorphes en
dehors d’un contexte d’héritage
ArrayList<Colorable> liste=new ArrayList<Colorable>();
liste.add(new Voiture());
liste.add(new Cercle());
liste.add(new Jouet());
liste.add(new Perruque());
this.paintItBlack(liste);
mercredi 23 octobre 13