2I002
UML, REPRÉSENTATION DES OBJETS
Vincent Guigue & Christophe Marsala
Philosophie
On ne programme pas pour soi-même... Mais pour les autres:
Respecter lescodes syntaxiques : majuscules, minuscules...
Donner desnoms explicites (classes, méthodes, attributs) Développer une documentationdu code (cf cours javadoc)
... Et proposer unevision synthétique d’un ensemble de classes: ⇒ UML
nom de la classe attributs
méthodes (et constructeurs)
+ code pour visualiser public/private
+ liens entre classes pour les dépendances (cf cours sur la composition)
Philosophie
On ne programme pas pour soi-même... Mais pour les autres:
Respecter lescodes syntaxiques : majuscules, minuscules...
Donner desnoms explicites (classes, méthodes, attributs) Développer une documentationdu code (cf cours javadoc)
... Et proposer unevision synthétique d’un ensemble de classes: ⇒ UML
nom de la classe attributs
méthodes (et constructeurs)
+ code pour visualiser public/private
+ liens entre classes pour les dépendances (cf cours sur la composition)
2/14
UML Client vs Développeur
Plusieurs types de diagrammes pour plusieurs usages:
Pour les développeurs: représentation complète
Pour les utilisateurs: représentation publicuniquement
Le code doit être pensé pour les autres:
Tous les noms doivent être aussi clairs que possible Un diagramme plus limité est plus facile à lire
Philosophie (suite)
2 manières de voir l’UML:
1 Outil pour unevisualisationglobale d’un code complexe
2 Outil de conception/ développement indépendant du langage Dans le cadre de 2i002: seulement l’approche 1
Limites de l’UML:
Vision architecte...
Mais pas d’analyse de l’exécution du code
Que se passe-t-il lors de l’exécution du programme:
Nouveau type de représentation:
Diagramme mémoire
4/14
Coté JVM: exécution du code
1 P o i n t p1 = new P o i n t ( 1 , 2 ) ; Comment décrire cette ligne de code?
Lavariablep, de type Point,référenceuneinstance dont les attributsx et y ont pour valeur respective 1 et 2.
Comment représenter cette ligne de code?
double x = 1 double y = 2
Point Point p1
Représentation des classes sans les méthodes Valeur des attributs
Type & noms des variables Lien de référencement
⇒les lignes de code s’enchainent: on raye, on trace des nouveaux liens etc... On représente ce qui se passe au cours de l’exécution du code.
1 p1 . move ( 0 , 1 ) ; // en i m a g i n a n t que l a methode e x i s t e
Coté JVM: exécution du code
1 P o i n t p1 = new P o i n t ( 1 , 2 ) ; Comment décrire cette ligne de code?
Lavariablep, de type Point,référenceuneinstance dont les attributsx et y ont pour valeur respective 1 et 2.
Comment représenter cette ligne de code?
double x = 1 double y = 2
Point Point p1
Représentation des classes sans les méthodes Valeur des attributs
Type & noms des variables Lien de référencement
⇒les lignes de code s’enchainent: on raye, on trace des nouveaux liens etc... On représente ce qui se passe au cours de l’exécution du code.
1 p1 . move ( 0 , 1 ) ; // en i m a g i n a n t que l a methode e x i s t e
5/14
Coté JVM: exécution du code
1 P o i n t p1 = new P o i n t ( 1 , 2 ) ; Comment décrire cette ligne de code?
Lavariablep, de type Point,référenceuneinstance dont les attributsx et y ont pour valeur respective 1 et 2.
Comment représenter cette ligne de code?
double x = 1 double y = 2
Point Point p1
Représentation des classes sans les méthodes Valeur des attributs
Type & noms des variables Lien de référencement
⇒les lignes de code s’enchainent: on raye, on trace des nouveaux liens etc... On représente ce qui se passe au cours de l’exécution du code.
1 p1 . move ( 0 , 1 ) ; // en i m a g i n a n t que l a methode e x i s t e
Coté JVM: exécution du code
1 P o i n t p1 = new P o i n t ( 1 , 2 ) ; Comment décrire cette ligne de code?
Lavariablep, de type Point,référenceuneinstance dont les attributsx et y ont pour valeur respective 1 et 2.
Comment représenter cette ligne de code?
double x = 1 double y = 2
Point Point p1
Représentation des classes sans les méthodes Valeur des attributs
Type & noms des variables Lien de référencement
⇒les lignes de code s’enchainent: on raye, on trace des nouveaux liens etc... On représente ce qui se passe au cours de l’exécution du code.
1 p1 . move ( 0 , 1 ) ; // en i m a g i n a n t que l a methode e x i s t e
5/14
Types de base vs Objet : signification de =
Lestypes de base et les objets ne se comportent pas de la même façon avec = Liste des types de base:
int, double, boolean, char, byte, short, long, float
1 d o u b l e a , b ;
2 a = 1 ;
3 b = a ; // d u p l i c a t i o n de l a v a l e u r 1
⇒Si best modifié, pas d’incidence sur a
et pour un Objet:
4 P o i n t p = new P o i n t ( 1 , 2 ) ;
5 P o i n t q = p ; // d u p l i c a t i o n de l a r e f e r e n c e . . .
6 // 1 s e u l e i n s t a n c e !
double x = 1 double y = 2
Point Point p
Point q
2 variables, 2 références, mais 1 seule instance
Types de base vs Objet : signification de =
Lestypes de base et les objets ne se comportent pas de la même façon avec = Liste des types de base:
int, double, boolean, char, byte, short, long, float
1 d o u b l e a , b ;
2 a = 1 ;
3 b = a ; // d u p l i c a t i o n de l a v a l e u r 1
⇒Si best modifié, pas d’incidence sur a et pour un Objet:
4 P o i n t p = new P o i n t ( 1 , 2 ) ;
5 P o i n t q = p ; // d u p l i c a t i o n de l a r e f e r e n c e . . .
6 // 1 s e u l e i n s t a n c e !
double x = 1 double y = 2
Point Point p
Point q
2 variables, 2 références, mais 1 seule instance
6/14
Types de base vs Objet : signification de =
Lestypes de base et les objets ne se comportent pas de la même façon avec = Liste des types de base:
int, double, boolean, char, byte, short, long, float
1 d o u b l e a , b ;
2 a = 1 ;
3 b = a ; // d u p l i c a t i o n de l a v a l e u r 1
⇒Si best modifié, pas d’incidence sur a et pour un Objet:
4 P o i n t p = new P o i n t ( 1 , 2 ) ;
5 P o i n t q = p ; // d u p l i c a t i o n de l a r e f e r e n c e . . .
6 // 1 s e u l e i n s t a n c e !
double x = 1 double y = 2
Point Point p
Point q
Clonage vs copie de surface
1 p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
2 P o i n t p1 = new P o i n t ( 1 , 2 ) ;
3 P o i n t p2 = p1 ;
4
5 P o i n t p3 = new P o i n t ( 1 , 2 ) ;
6 P o i n t p4 = new P o i n t ( 1 , 2 ) ;
7 }
double x = 1 double y = 2
Point Point p1
Point p2
double x = 1 double y = 2
Point Point p3
Point p4
double x = 1 double y = 2
Point
Les variables p1et p2référencent la même instance
p3et p4référencent des instances différentes
7/14
Références & arguments de fonctions
Passer un argument à une fonction revient à utiliser un signe = ... Objets et types de base se comportent différemment !
1 // c l a s s e UnObjet ,
2 // ( c l a s s e s a n s i m p o r t a n c e )
3 . . .
4 p u b l i c v o i d m a F o n c t i o n 1 ( P o i n t p) {
5 . . .
6 p. move ( 1 . , 1 . ) ;
7 . . .
8 }
9
10 p u b l i c v o i d m a F o n c t i o n 2 (d o u b l e d) {
11 . . .
12 d = 3 . ; // s y n t a x e c o r r e c t e
13 // m a i s t r e s moche !
14 . . .
15 }
1 // d a n s l e main
2 UnObjet o b j = new UnObjet ( ) ;
3
4 P o i n t p = new P o i n t ( 1 . , 2 . ) ;
5 d o u b l e d = 2 . ;
6
7 o b j . m a F o n c t i o n 1 ( p ) ;
8 o b j . m a F o n c t i o n 2 ( d ) ;
9
10 // p a p o u r a t t r i b u t s ( x = 2 . , y = 3 . )
11 // d v a u t 2
Quand un objet est passé en argument:
il n’y a pas duplication de l’instance (simplement 2 références vers 1 instance)
Types de base vs Objet : signification de ==
Opérateur == : prend 2 opérandes de même typeet retourne un boolean Type de base : vérification de l’égalité des valeurs
Objet : vérification de l’égalitédes références
ATTENTIONaux classes enveloppes (qui sont des objets)
1 d o u b l e d1 = 1 . ;
2 d o u b l e d2 = 1 . ;
3 S y s t e m . o u t . p r i n t l n ( d1==d2 ) ; // a f f i c h a g e de t r u e
4 // d a n s l a c o n s o l e
5 P o i n t p1 = new P o i n t ( 1 , 2 ) ;
6 P o i n t p2 = p1 ;
7 S y s t e m . o u t . p r i n t l n ( p1==p2 ) ; // a f f i c h a g e de true
8
9 P o i n t p3 = new P o i n t ( 1 , 2 ) ;
10 P o i n t p4 = new P o i n t ( 1 , 2 ) ;
11 S y s t e m . o u t . p r i n t l n ( p3==p4 ) ; // a f f i c h a g e de false
12 D o u b l e d3 = 1 . ; // c l a s s e e n v e l o p p e D o u b l e = o b j e t
13 D o u b l e d4 = 1 . ;
14 S y s t e m . o u t . p r i n t l n ( d3==d4 ) ; // a f f i c h a g e de false
9/14
Types de base vs Objet : signification de ==
Opérateur == : prend 2 opérandes de même typeet retourne un boolean Type de base : vérification de l’égalité des valeurs
Objet : vérification de l’égalitédes références
ATTENTIONaux classes enveloppes (qui sont des objets)
1 d o u b l e d1 = 1 . ;
2 d o u b l e d2 = 1 . ;
3 S y s t e m . o u t . p r i n t l n ( d1==d2 ) ; // a f f i c h a g e de t r u e
4 // d a n s l a c o n s o l e
5 P o i n t p1 = new P o i n t ( 1 , 2 ) ;
6 P o i n t p2 = p1 ;
7 S y s t e m . o u t . p r i n t l n ( p1==p2 ) ; // a f f i c h a g e de true
8
9 P o i n t p3 = new P o i n t ( 1 , 2 ) ;
10 P o i n t p4 = new P o i n t ( 1 , 2 ) ;
11 S y s t e m . o u t . p r i n t l n ( p3==p4 ) ; // a f f i c h a g e de false
12 D o u b l e d3 = 1 . ; // c l a s s e e n v e l o p p e D o u b l e = o b j e t
13 D o u b l e d4 = 1 . ;
14 S y s t e m . o u t . p r i n t l n ( d3==d4 ) ; // a f f i c h a g e de false
Types de base vs Objet : signification de ==
Opérateur == : prend 2 opérandes de même typeet retourne un boolean Type de base : vérification de l’égalité des valeurs
Objet : vérification de l’égalitédes références
ATTENTIONaux classes enveloppes (qui sont des objets)
1 d o u b l e d1 = 1 . ;
2 d o u b l e d2 = 1 . ;
3 S y s t e m . o u t . p r i n t l n ( d1==d2 ) ; // a f f i c h a g e de t r u e
4 // d a n s l a c o n s o l e
5 P o i n t p1 = new P o i n t ( 1 , 2 ) ;
6 P o i n t p2 = p1 ;
7 S y s t e m . o u t . p r i n t l n ( p1==p2 ) ; // a f f i c h a g e de true
8
9 P o i n t p3 = new P o i n t ( 1 , 2 ) ;
10 P o i n t p4 = new P o i n t ( 1 , 2 ) ;
11 S y s t e m . o u t . p r i n t l n ( p3==p4 ) ; // a f f i c h a g e de false
12 D o u b l e d3 = 1 . ; // c l a s s e e n v e l o p p e D o u b l e = o b j e t
13 D o u b l e d4 = 1 . ;
14 S y s t e m . o u t . p r i n t l n ( d3==d4 ) ; // a f f i c h a g e de false
9/14
Classes enveloppes
Les types de base en JAVA sont doublés dewrappers ou classes enveloppes pour:
utiliser les classes génériques (cf cours ArrayList) fournir quelques outils fort utiles
int, double, boolean, char, byte, short, long, float ⇒ Integer, Double...
Outils
1 D o u b l e d1 = D o u b l e . MAX_VALUE ; // v a l e u r maximum p o s s i b l e
2 D o u b l e d2 = D o u b l e . POSITIVE_INFINITY ; // v a l e u r s p e c i f i q u e
3 // g e r e e d a n s l e s o p e r a t i o n s
4 D o u b l e d3 = D o u b l e . v a l u e o f (" 3 . 5 ") ; // S t r i n g => d o u b l e
5 // D o u b l e . isNaN ( d o u b l e d ) , D o u b l e . i s I n f i n i t e ( d o u b l e d ) . . .
Documentation:http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html
6 // c o n v e r s i o n s i m p l i c i t e s = ( un ) b o x i n g ( d e p u i s JAVA 5 )
7 d o u b l e d4 = d1 ;
8 D o u b l e d5 = d4 ;
Classes enveloppes
Les types de base en JAVA sont doublés dewrappers ou classes enveloppes pour:
utiliser les classes génériques (cf cours ArrayList) fournir quelques outils fort utiles
int, double, boolean, char, byte, short, long, float ⇒ Integer, Double...
Outils
1 D o u b l e d1 = D o u b l e . MAX_VALUE ; // v a l e u r maximum p o s s i b l e
2 D o u b l e d2 = D o u b l e . POSITIVE_INFINITY ; // v a l e u r s p e c i f i q u e
3 // g e r e e d a n s l e s o p e r a t i o n s
4 D o u b l e d3 = D o u b l e . v a l u e o f (" 3 . 5 ") ; // S t r i n g => d o u b l e
5 // D o u b l e . isNaN ( d o u b l e d ) , D o u b l e . i s I n f i n i t e ( d o u b l e d ) . . .
Documentation:http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html
6 // c o n v e r s i o n s i m p l i c i t e s = ( un ) b o x i n g ( d e p u i s JAVA 5 )
7 d o u b l e d4 = d1 ;
8 D o u b l e d5 = d4 ;
10/14
Classe enveloppe: des objets avant tout
Historique:
A l’origine: Philosophie tout objet
⇒ propre, mais pas pratique Evolution: plus de dérogation pour faciliter les usages
⇒ classes enveloppes bcp moins utilisées
⇒Classe enveloppe = objet !!!
1 d o u b l e d1b = 1 . ;
2 d o u b l e d2b = d1b ;
3 d o u b l e d3b = 1 . ;
4 S y s t e m . o u t . p r i n t l n ( d1b == d2b ) ;
5 S y s t e m . o u t . p r i n t l n ( d1b == d3b ) ;
6 // t r u e & t r u e
7 D o u b l e d1 = 1 . ;
8 D o u b l e d2 = d1 ;
9 D o u b l e d3 = 1 . ;
10 S y s t e m . o u t . p r i n t l n ( d1 == d2 ) ;
11 S y s t e m . o u t . p r i n t l n ( d1 == d3 ) ;
12 // t r u e & false
Classe enveloppe: des objets avant tout
Historique:
A l’origine: Philosophie tout objet
⇒ propre, mais pas pratique Evolution: plus de dérogation pour faciliter les usages
⇒ classes enveloppes bcp moins utilisées
⇒Classe enveloppe = objet !!!
1 d o u b l e d1b = 1 . ;
2 d o u b l e d2b = d1b ;
3 d o u b l e d3b = 1 . ;
4 S y s t e m . o u t . p r i n t l n ( d1b == d2b ) ;
5 S y s t e m . o u t . p r i n t l n ( d1b == d3b ) ;
6 // t r u e & t r u e
7 D o u b l e d1 = 1 . ;
8 D o u b l e d2 = d1 ;
9 D o u b l e d3 = 1 . ;
10 S y s t e m . o u t . p r i n t l n ( d1 == d2 ) ;
11 S y s t e m . o u t . p r i n t l n ( d1 == d3 ) ;
12 // t r u e & false
11/14
Classe enveloppe: des objets avant tout
Historique:
A l’origine: Philosophie tout objet
⇒ propre, mais pas pratique Evolution: plus de dérogation pour faciliter les usages
⇒ classes enveloppes bcp moins utilisées
⇒Classe enveloppe = objet !!!
1 d o u b l e d1b = 1 . ;
2 d o u b l e d2b = d1b ;
3 d o u b l e d3b = 1 . ;
4 S y s t e m . o u t . p r i n t l n ( d1b == d2b ) ;
5 S y s t e m . o u t . p r i n t l n ( d1b == d3b ) ;
6 // t r u e & t r u e
7 D o u b l e d1 = 1 . ;
8 D o u b l e d2 = d1 ;
9 D o u b l e d3 = 1 . ;
10 S y s t e m . o u t . p r i n t l n ( d1 == d2 ) ;
11 S y s t e m . o u t . p r i n t l n ( d1 == d3 ) ;
12 // t r u e & false
Classe enveloppe: des objets avant tout
Historique:
A l’origine: Philosophie tout objet
⇒ propre, mais pas pratique Evolution: plus de dérogation pour faciliter les usages
⇒ classes enveloppes bcp moins utilisées
⇒Classe enveloppe = objet !!!
1 d o u b l e d1b = 1 . ;
2 d o u b l e d2b = d1b ;
3 d o u b l e d3b = 1 . ;
4 S y s t e m . o u t . p r i n t l n ( d1b == d2b ) ;
5 S y s t e m . o u t . p r i n t l n ( d1b == d3b ) ;
6 // t r u e & t r u e
7 D o u b l e d1 = 1 . ;
8 D o u b l e d2 = d1 ;
9 D o u b l e d3 = 1 . ;
10 S y s t e m . o u t . p r i n t l n ( d1 == d2 ) ;
11 S y s t e m . o u t . p r i n t l n ( d1 == d3 ) ;
12 // t r u e & false
11/14
Pointeur null
Que se passe-t-il quand on déclare une variable (sans l’instancier)?
1 P o i n t p ;
p vaut null.
On peut écrire de manière équivalente :
1 P o i n t p = n u l l;
On ne peut pas invoquer de méthode
1 p . move ( 1 . , 2 . ) ; // => CRASH de l ’ e x e c u t i o n :
2 // N u l l P o i n t e r E x c e p t i o n
N’importe quel objet peut être nullet réciproquement, on peut donner nullà n’importe quel endroit où un objet est attendu... Même si ça provoque parfois des crashs.
1 // c l a s s e UnObjet ,
2 // ( c l a s s e s a n s i m p o r t a n c e ) 3 . . .
4 p u b l i c v o i d m a F o n c t i o n ( P o i n t p ) { 5 . . .
6 p . move ( 1 . , 1 . ) ; 7 . . .
8 }
1 // d a n s l e main
2 U n O b j e t o b j = new U n O b j e t ( ) ; 3
4 o b j . m a F o n c t i o n (n u l l) ;
Pointeur null
Que se passe-t-il quand on déclare une variable (sans l’instancier)?
1 P o i n t p ;
p vaut null.
On peut écrire de manière équivalente :
1 P o i n t p = n u l l;
On ne peut pas invoquer de méthode
1 p . move ( 1 . , 2 . ) ; // => CRASH de l ’ e x e c u t i o n :
2 // N u l l P o i n t e r E x c e p t i o n
N’importe quel objet peut être nullet réciproquement, on peut donner nullà n’importe quel endroit où un objet est attendu... Même si ça provoque parfois des crashs.
1 // c l a s s e UnObjet ,
2 // ( c l a s s e s a n s i m p o r t a n c e ) 3 . . .
4 p u b l i c v o i d m a F o n c t i o n ( P o i n t p ) { 5 . . .
6 p . move ( 1 . , 1 . ) ; 7 . . .
8 }
1 // d a n s l e main
2 U n O b j e t o b j = new U n O b j e t ( ) ; 3
4 o b j . m a F o n c t i o n (n u l l) ;
12/14
Pointeur null
Que se passe-t-il quand on déclare une variable (sans l’instancier)?
1 P o i n t p ;
p vaut null.
On peut écrire de manière équivalente :
1 P o i n t p = n u l l;
On ne peut pas invoquer de méthode
1 p . move ( 1 . , 2 . ) ; // => CRASH de l ’ e x e c u t i o n :
2 // N u l l P o i n t e r E x c e p t i o n
N’importe quel objet peut être nullet réciproquement, on peut donner nullà n’importe quel endroit où un objet est attendu... Même si ça provoque parfois des crashs.
1 // c l a s s e UnObjet ,
2 // ( c l a s s e s a n s i m p o r t a n c e ) 3 . . .
4 p u b l i c v o i d m a F o n c t i o n ( P o i n t p ) { 5 . . .
6 p . move ( 1 . , 1 . ) ; 7 . . .
1 // d a n s l e main
2 U n O b j e t o b j = new U n O b j e t ( ) ; 3
4 o b j . m a F o n c t i o n (n u l l) ;
NullPointerException: une recherche parfois difficile
Un truc classique, mais catastrophique...
1 p u b l i c c l a s s V e c t e u r { 2 // un p e u e n a v a n c e 3 // s u r l a c o m p o s i t i o n . . . 4 p r i v a t e P o i n t a , b ;
5 p u b l i c V e c t e u r ( P o i n t p1 , P o i n t p2 ) { 6 P o i n t a = p1 ; P o i n t b=p2 ;
7 }
8 p u b l i c v o i d move (d o u b l e d ) { 9 a . move ( d ) ; b . move ( d ) ;
10 }
1 p u b l i c c l a s s T e s t V e c t e u r { 2 p u b l i c s t a t i c
3 v o i d main ( S t r i n g [ ] a r g s ) { 4 P o i n t p = new P o i n t ( 1 . , 2 . ) ; 5 P o i n t p2 = new P o i n t ( 3 . , 5 . ) ; 6 V e c t e u r v = new V e c t e u r ( p , p2 ) ; 7
8 v . move ( 3 ) ;
9 }
10 }
Crash NullPointerException dans Vecteur à la ligne 9 Venant de mainà la ligne 8
13/14
NullPointerException: une recherche parfois difficile
Un truc classique, mais catastrophique...
1 p u b l i c c l a s s V e c t e u r { 2 // un p e u e n a v a n c e 3 // s u r l a c o m p o s i t i o n . . . 4 p r i v a t e P o i n t a , b ;
5 p u b l i c V e c t e u r ( P o i n t p1 , P o i n t p2 ) { 6 P o i n t a = p1 ; P o i n t b=p2 ;
7 }
8 p u b l i c v o i d move (d o u b l e d ) { 9 a . move ( d ) ; b . move ( d ) ;
10 }
1 p u b l i c c l a s s T e s t V e c t e u r { 2 p u b l i c s t a t i c
3 v o i d main ( S t r i n g [ ] a r g s ) { 4 P o i n t p = new P o i n t ( 1 . , 2 . ) ; 5 P o i n t p2 = new P o i n t ( 3 . , 5 . ) ; 6 V e c t e u r v = new V e c t e u r ( p , p2 ) ; 7
8 v . move ( 3 ) ;
9 }
10 }
Crash NullPointerException dans Vecteur à la ligne 9 Venant de mainà la ligne 8
Execution d’une méthode
Une méthode est exécutée sur une instance...
1 P o i n t p = new P o i n t ( 1 , 2 ) ;
2 P o i n t p2 = p ;
3 p . move ( 1 . , 1 . ) ;
4 // methode e x e c u t e e s u r l ’ i n s t a n c e
5 // ( q u i e s t r e f e r e n c e e p a r p e t p2 )
6 S y s t e m . o u t . p r i n t l n ( p2 ) ;
7 // [ x = 2 . , y = 3 . ]
⇒Il faut toujours se représenter ce qui se passe dans la mémoire lors de l’exécution d’un programme.
14/14