LU2IN002 STATIC
Vincent Guigue & Christophe Marsala
Static6= POO
POO
Un objet protège ses attributs
Un objet possède des méthodes pour gérer ses attributs
Static
Les attributs/méthodesstatic ne dépendent pas d’un objet Tous les objets d’une classe ont accès aux mêmes informations static
Usage
1 Création d’une instance
2 Appel de méthode sur cette instance
Usage
1 Appel de méthode/attribut indépendamment des instances
Usage de static
Attributs static (=variable de classe):
partager des informations entre les instances d’une classe Compteurs
Combien d’instances dePointont-elles été créées?
Question non triviale avec les outils actuels !
Liste des objets créés
Je voudrais accéder à n’importe quelPointcréé jusqu’ici...
Constantes (cas particulier, cf plus loin) π...
Méthodes static:
outils non reliés à une instance Outils (opérations entre instances, opérations annexes) Accesseur à un attribut static
Singleton
Usage de static
Attributs static (=variable de classe):
partager des informations entre les instances d’une classe Compteurs
Liste des objets créés
Constantes (cas particulier, cf plus loin) Méthodes static:
outils non reliés à une instance Outils (opérations entre instances, opérations annexes) Ex: cos, une méthode n’utilisant aucun attribut, utilisable directement, sans instantiation d’un objet de la classe Math
Accesseur à un attribut static Singleton
Syntaxe/philosophie comparative
Programmation objet:
1 // I n s t a n t i a t i o n
2 P o i n t p = new P o i n t ( 1 , 2 ) ;
3
4 // I n v o c a t i o n de methode
5 // SUR L’INSTANCE
6 p . move ( 3 , 3 ) ;
7 p . t o S t r i n g ( ) ;
8 . . .
Philosophie:
Les méthodes accèdent / modifient l’instance
Programmationstatic:
1 // Pas d ’ i n s t a n t i a t i o n de l a c l a s s e
2 // A p p e l d i r e c t e m e n t s u r l a c l a s s e
3 d o u b l e p i = Math . P I ;
4
5 // P a r e i l p o u r l e s m e t h o d e s
6 d o u b l e d = Math . c o s ( p i ) ;
Philosophie:
Pas d’instance, pas d’accès aux attributs
Constante indépendante Méthode indépendante
⇒ Essayons maintenant de mélanger les 2 philosophies pour faire des choses nouvelles
Syntaxe/philosophie comparative
Programmation objet:
1 // I n s t a n t i a t i o n
2 P o i n t p = new P o i n t ( 1 , 2 ) ;
3
4 // I n v o c a t i o n de methode
5 // SUR L’INSTANCE
6 p . move ( 3 , 3 ) ;
7 p . t o S t r i n g ( ) ;
8 . . .
Philosophie:
Les méthodes accèdent / modifient l’instance
Programmationstatic:
1 // Pas d ’ i n s t a n t i a t i o n de l a c l a s s e
2 // A p p e l d i r e c t e m e n t s u r l a c l a s s e
3 d o u b l e p i = Math . P I ;
4
5 // P a r e i l p o u r l e s m e t h o d e s
6 d o u b l e d = Math . c o s ( p i ) ;
Philosophie:
Pas d’instance, pas d’accès aux attributs
Constante indépendante Méthode indépendante
⇒ Essayons maintenant de mélanger les 2 philosophies pour faire des choses nouvelles
Syntaxe/philosophie comparative
Programmation objet:
1 // I n s t a n t i a t i o n
2 P o i n t p = new P o i n t ( 1 , 2 ) ;
3
4 // I n v o c a t i o n de methode
5 // SUR L’INSTANCE
6 p . move ( 3 , 3 ) ;
7 p . t o S t r i n g ( ) ;
8 . . .
Philosophie:
Les méthodes accèdent / modifient l’instance
Programmationstatic:
1 // Pas d ’ i n s t a n t i a t i o n de l a c l a s s e
2 // A p p e l d i r e c t e m e n t s u r l a c l a s s e
3 d o u b l e p i = Math . P I ;
4
5 // P a r e i l p o u r l e s m e t h o d e s
6 d o u b l e d = Math . c o s ( p i ) ;
Philosophie:
Pas d’instance, pas d’accès aux attributs
Constante indépendante Méthode indépendante
⇒ Essayons maintenant de mélanger les 2 philosophies pour faire des choses nouvelles
Cas classique: comptage d’instances
Combien d’instances dePointont-elles été créées?
Question non triviale avec les outils actuels !
Identifiant unique/comptage des instances
1 P o i n t p1 = new P o i n t ( ) ; // c o n s t r u c t e u r random
2 P o i n t p2 = p1 ;
3 P o i n t p3 = new P o i n t ( 3 , 5 ) ;
4 . . .
Combien d’instance?
Peut-on attribuer à chaque Point a un identifiant unique (lié à son ordre de création)?
Comptage d’instances: syntaxe standard Forme standard
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c i n t cpt = 0 ; // i n i t i a l i s a t i o n o b l i g a t o i r e i c i
3 p r i v a t e i n t id; // i n i t i a l i s a t i o n i n t e r d i t e i c i (−> c o n s t r )
4 p r i v a t e d o u b l e x,y;
5
6 p u b l i c P o i n t (d o u b l e x , d o u b l e y ) {
7 t h i s. x = x ; t h i s. y = y ;
8 i d = c p t ++; // ou : i d = c p t ; c p t ++;
9 }
Chaque Point a : unx, uny, unid
Tous les Point partagent:
un compteurcpt
Le partage permet de raisonner sur des concepts qui dépassent UNE SEULE instance
Comptage & représentation mémoire
1 P o i n t p1 = new P o i n t ( ) ;
2 P o i n t p2 = p1 ;
3 P o i n t p3 = new P o i n t ( 3 , 5 ) ;
Où se trouve l’id?, Où se trouve le compteur? (dans une représentation mémoire)
Comptage & représentation mémoire
1 P o i n t p1 = new P o i n t ( ) ;
2 P o i n t p2 = p1 ;
3 P o i n t p3 = new P o i n t ( 3 , 5 ) ;
Où se trouve l’id?, Où se trouve le compteur? (dans une représentation mémoire)
double x = 0.556 double y = 3.966 id = 0
Point Point p1
double x = 3 double y = 5 id = 1
Point Point p2
Point p3
cpt = 2
Zone commune Point
Les instances voient la zone commune
Comptage & représentation mémoire
1 P o i n t p1 = new P o i n t ( ) ;
2 P o i n t p2 = p1 ;
3 P o i n t p3 = new P o i n t ( 3 , 5 ) ;
Où se trouve l’id?, Où se trouve le compteur? (dans une représentation mémoire)
double x = 0.556 double y = 3.966 id = 0
Point Point p1
double x = 3 double y = 5 id = 1
Point Point p2
Point p3
cpt = 2
Zone commune Point
La zone static ne connait pas les instances
Comptage d’instances: syntaxe standard (2) Forme standard
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c i n t c p t = 0 ; // i n i t i a l i s a t i o n o b l i g a t o i r e i c i
3 p r i v a t e i n t i d ; // i n i t i a l i s a t i o n i n t e r d i t e i c i (−> c o n s t r )
4 p r i v a t e d o u b l e x , y ;
5
6 p u b l i c P o i n t (d o u b l e x , d o u b l e y ) {
7 t h i s. x = x ; t h i s. y = y ;
8 i d = c p t ++; // ou : i d = c p t ; c p t ++;
9 }
10
11 // g a r a n t i e de bonne g e s t i o n d e s i d
12 p u b l i c P o i n t ( ) {
13 t h i s( Math . random ( )∗1 0 , Math . random ( )∗1 0 ) ;
14 }
Piège: attention aux constructeurs multiples
⇒ usage dethis()très fortement conseillé pour passer toujours par le constructeur de référence et bien compter.
Static ou non static : toujours vérifier
Toujours vérifierqu’une variable staticne décrit pasuneinstance
⇒sinon, on a fait une faute de conception
le compteur d’instances est commun pour toutes les instances
⇒ static l’identifiant est spécifique à chaque instance
⇒ non static
Exercice du td: la classeChien
nom chercherLivreSurChiens()
aboyer() vidéothèqueSurChiens siteWebSurChiens metsPrefere
siteWebDuChien bibliographieSurChiens siteWebSPA dateNaissance
couleurDuPoil manger()
courir() regarderDVD()
Autre exemple: conserver tous les points créés jusqu’ici
1 Je suis dans la classe Point
2 Déclaration d’un tableau –taille variable– de Point
Partagé entre toutes les instances de Point
3 static ⇒instantiation immédiate
4 Dès qu’unPoint est créé, on l’ajoute dans le tableau
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c A r r a y L i s t <P o i n t > t a b = new A r r a y L i s t <P o i n t > ( ) ;
3 p u b l i c P o i n t (d o u b l e x , d o u b l e y ) {
4 [ . . . ] // i n s t r u c t i o n s d i v e r e s
5 t a b . add (t h i s) ; // a j o u t de l ’ i n s t a n c e c o u r a n t e d a n s l e t a b l e a u
6 }
⇒Possibilités de recherche dans l’historiques etc...
Autre exemple: conserver tous les points créés jusqu’ici
1 Je suis dans la classe Point
2 Déclaration d’un tableau –taille variable– de Point
Partagé entre toutes les instances de Point
3 static ⇒instantiation immédiate
4 Dès qu’unPoint est créé, on l’ajoute dans le tableau
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c A r r a y L i s t <P o i n t > t a b = new A r r a y L i s t <P o i n t > ( ) ;
3 p u b l i c P o i n t (d o u b l e x , d o u b l e y ) {
4 [ . . . ] // i n s t r u c t i o n s d i v e r e s
5 t a b . add (t h i s) ; // a j o u t de l ’ i n s t a n c e c o u r a n t e d a n s l e t a b l e a u
6 }
⇒Possibilités de recherche dans l’historiques etc...
Autre exemple: conserver tous les points créés jusqu’ici
1 Je suis dans la classe Point
2 Déclaration d’un tableau –taille variable– de Point
Partagé entre toutes les instances de Point
3 static⇒ instantiation immédiate
4 Dès qu’unPoint est créé, on l’ajoute dans le tableau
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c A r r a y L i s t <P o i n t > t a b = new A r r a y L i s t <P o i n t > ( ) ;
3 p u b l i c P o i n t (d o u b l e x , d o u b l e y ) {
4 [ . . . ] // i n s t r u c t i o n s d i v e r e s
5 t a b . add (t h i s) ; // a j o u t de l ’ i n s t a n c e c o u r a n t e d a n s l e t a b l e a u
6 }
⇒Possibilités de recherche dans l’historiques etc...
Autre exemple: conserver tous les points créés jusqu’ici
1 Je suis dans la classe Point
2 Déclaration d’un tableau –taille variable– de Point
Partagé entre toutes les instances de Point
3 static⇒ instantiation immédiate
4 Dès qu’unPoint est créé, on l’ajoute dans le tableau
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c A r r a y L i s t <P o i n t > t a b = new A r r a y L i s t <P o i n t > ( ) ;
3 p u b l i c P o i n t (d o u b l e x , d o u b l e y ) {
4 [ . . . ] // i n s t r u c t i o n s d i v e r e s
5 t a b . add (t h i s) ; // a j o u t de l ’ i n s t a n c e c o u r a n t e d a n s l e t a b l e a u
6 }
⇒Possibilités de recherche dans l’historiques etc...
Fonction static Boite à outils:
Génération de nom aléatoire (lettre aléatoire ou alternance voyelles/consonnes)
Distance entre Points (formulation alternative à celle intra-classe),
possibilité de définitions multiples pour prendre en compte des contraintes
optimisation ultérieure
L’exemple de la classe Math
Génération aléatoire de lettre:
1 p u b l i c c l a s s A l e a {
2 p u b l i c s t a t i c c h a r l e t t r e ( ) {
3 r e t u r n (c h a r) ( ( (c h a r) ( Math . random ( )∗(’ z ’−’ a ’+1)))+’ a ’) ;
4 }
5 }
⇒lettre()ne dépend d’aucun attribut Usage:
1 // d a n s un main
2 c h a r c = A l e a . l e t t r e ( ) ; // t r e s s i m p l e !
Fonction static Boite à outils:
Génération de nom aléatoire (lettre aléatoire ou alternance voyelles/consonnes)
Distance entre Points (formulation alternative à celle intra-classe),
possibilité de définitions multiples pour prendre en compte des contraintes
optimisation ultérieure
L’exemple de la classe Math Génération aléatoire de lettre:
1 p u b l i c c l a s s A l e a {
2 p u b l i c s t a t i c c h a r l e t t r e ( ) {
3 r e t u r n (c h a r) ( ( (c h a r) ( Math . random ( )∗(’ z ’−’ a ’+1)))+’ a ’) ;
4 }
5 }
⇒lettre()ne dépend d’aucun attribut
Usage:
1 // d a n s un main
2 c h a r c = A l e a . l e t t r e ( ) ; // t r e s s i m p l e !
Fonction static Boite à outils:
Génération de nom aléatoire (lettre aléatoire ou alternance voyelles/consonnes)
Distance entre Points (formulation alternative à celle intra-classe),
possibilité de définitions multiples pour prendre en compte des contraintes
optimisation ultérieure
L’exemple de la classe Math Génération aléatoire de lettre:
1 p u b l i c c l a s s A l e a {
2 p u b l i c s t a t i c c h a r l e t t r e ( ) {
3 r e t u r n (c h a r) ( ( (c h a r) ( Math . random ( )∗(’ z ’−’ a ’+1)))+’ a ’) ;
4 }
5 }
⇒lettre()ne dépend d’aucun attribut Usage:
1 // d a n s un main
2 c h a r c = A l e a . l e t t r e ( ) ; // t r e s s i m p l e !
Digression sur les classes outils
Si une classe n’a pas vocation à être instanciée...
Il faut interdire la possibilité de le faire !
Par défaut, on interdit tout... Et particulièrement ce que l’on n’est pas censé faire
⇒mais commentinterdire l’instanciation?
Rappel:
pas de constructeur = constructeur sans argument, public, qui ne fait rien.
= possibilité de créer une instance
1 p u b l i c c l a s s A l e a {
2 private A l e a ( ) {
3 // c o d e v i d e , m a i s a c c o l a d e s o b l i g a t o i r e s
4 }
5 p u b l i c s t a t i c c h a r l e t t r e ( ) {
6 [ . . . ]
7 }
8 }
Digression sur les classes outils
Si une classe n’a pas vocation à être instanciée...
Il faut interdire la possibilité de le faire !
Par défaut, on interdit tout... Et particulièrement ce que l’on n’est pas censé faire
⇒mais commentinterdire l’instanciation?
Rappel:
pas de constructeur = constructeur sans argument, public, qui ne fait rien.
= possibilité de créer une instance
1 p u b l i c c l a s s A l e a {
2 private A l e a ( ) {
3 // c o d e v i d e , m a i s a c c o l a d e s o b l i g a t o i r e s
4 }
5 p u b l i c s t a t i c c h a r l e t t r e ( ) {
6 [ . . . ]
7 }
8 }
Un fonctionnement asymétrique
les instances voient ce qui est static
les parties static ne voient pas les instances
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c i n t c p t = 0 ;
3 p r i v a t e i n t i d ;
4 p r i v a t e d o u b l e x , y ;
5 . . .
6 // Cas 1 : OK methode s t a t i c , a c c e s v a r i a b l e s t a t i c
7 p u b l i c s t a t i c i n t g e t C p t ( ) {r e t u r n c p t ; }
8 // Cas 2 : OK methode d ’ i n s t a n c e , a c c e s v a r i a b l e s t a t i c
9 p u b l i c i n t g e t C p t I n s t ( ) {r e t u r n c p t ; }
10 // Cas 3 : KO methode s t a t i c , a c c e s v a r i a b l e d ’ i n s t a n c e
11 p u b l i c s t a t i c i n t g e t I D ( ) {r e t u r n i d ; } // non sens !!
Depuis le main:
1 P o i n t p1 = new P o i n t ( ) ;
2 // s y n t a x e n a t u r e l l e :
3 P o i n t . g e t C p t ( ) ;
4 // syntaxe possible (mais pas recommandée)
5 p1 . g e t C p t ( ) ;
6 // syntaxe impossible (évidemment) :
7 P o i n t . g e t C p t I n s t ( ) ;
Un fonctionnement asymétrique
les instances voient ce qui est static
les parties static ne voient pas les instances
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c i n t c p t = 0 ;
3 p r i v a t e i n t i d ;
4 p r i v a t e d o u b l e x , y ;
5 . . .
6 // Cas 1 : OK methode s t a t i c , a c c e s v a r i a b l e s t a t i c
7 p u b l i c s t a t i c i n t g e t C p t ( ) {r e t u r n c p t ; }
8 // Cas 2 : OK methode d ’ i n s t a n c e , a c c e s v a r i a b l e s t a t i c
9 p u b l i c i n t g e t C p t I n s t ( ) {r e t u r n c p t ; }
10 // Cas 3 : KO methode s t a t i c , a c c e s v a r i a b l e d ’ i n s t a n c e
11 p u b l i c s t a t i c i n t g e t I D ( ) {r e t u r n i d ; } // non sens !!
Depuis le main:
1 P o i n t p1 = new P o i n t ( ) ;
2 // s y n t a x e n a t u r e l l e :
3 P o i n t . g e t C p t ( ) ;
4 // syntaxe possible (mais pas recommandée)
5 p1 . g e t C p t ( ) ;
6 // syntaxe impossible (évidemment) :
7 P o i n t . g e t C p t I n s t ( ) ;
Un fonctionnement asymétrique
les instances voient ce qui est static
les parties static ne voient pas les instances
1 p u b l i c c l a s s P o i n t {
2 p r i v a t e s t a t i c i n t c p t = 0 ;
3 p r i v a t e i n t i d ;
4 p r i v a t e d o u b l e x , y ;
5 . . .
6 // Cas 1 : OK methode s t a t i c , a c c e s v a r i a b l e s t a t i c
7 p u b l i c s t a t i c i n t g e t C p t ( ) {r e t u r n c p t ; }
8 // Cas 2 : OK methode d ’ i n s t a n c e , a c c e s v a r i a b l e s t a t i c
9 p u b l i c i n t g e t C p t I n s t ( ) {r e t u r n c p t ; }
10 // Cas 3 : KO methode s t a t i c , a c c e s v a r i a b l e d ’ i n s t a n c e
11 p u b l i c s t a t i c i n t g e t I D ( ) {r e t u r n i d ; } // non sens !!
Depuis le main:
1 P o i n t p1 = new P o i n t ( ) ;
2 // s y n t a x e n a t u r e l l e :
3 P o i n t . g e t C p t ( ) ;
4 // syntaxe possible (mais pas recommandée)
5 p1 . g e t C p t ( ) ;
6 // syntaxe impossible (évidemment) :
7 P o i n t . g e t C p t I n s t ( ) ;
Singleton
Pas d’accès au constructeur
Méthode pour récupérer LA SEULE instance existante
1 p u b l i c c l a s s S i n g l e t o n {
2 p r i v a t e s t a t i c f i n a l S i n g l e t o n INSTANCE = new S i n g l e t o n ( ) ;
3
4 p r i v a t e S i n g l e t o n ( ) {}
5
6 p u b l i c s t a t i c S i n g l e t o n g e t I n s t a n c e ( ) {r e t u r n INSTANCE ; }
7 }
Cas d’usage : définition d’un nouveau type
ClasseMonBooleen, constructeur privé, deux attributs static Accesseur static MonBooleen MonBooleen.getTrue(), MonBooleen MonBooleen.getFalse()
Dans le main, possibilité d’utiliser ==
Bilan...
Quand on vous parle destatic, n’oubliez pas:
Ce sont des cas très particuliers Assez rare
N’oubliez pas les bonnes pratiques de la POO!!!!!