1 Types énumérés
Transcription
1 Types énumérés
Licence 2e année Année universitaire 2007/2008 APO Fonctionnalités JAVA avancées Dans un soucis de standardisation des concepts objets, JAVA intègre de nouvelles fonctionnalités. Ces dernières permettent un syntaxe plus intuitive et une plus forte ressemblance avec le C++. 1 Types énumérés Les types énumérés permettent la définition d’une liste homogène de constantes, identifiées par son nom. La syntaxe est semblable à celle d’une classe. p u b l i c enum NomEnumeration { VALEUR_1 , VALEUR_2 , ... , VALEUR_n ; } Exemple : p u b l i c enum C o u l e u r { ROUGE, JAUNE , BLEU , NOIR , BLANC, ORANGE, VIOLET , VERT ; } 1.1 Ordre des éléments Les valeurs d’un type énuméré possède un ordre naturel est qui est celui de leur définition : VALEUR_1 < VALEUR_2 < ... VALEUR_n. En fait, un type énuméré implémente l’interface Comparable : C o u l e u r c1 , c2 ; c1 = C o u l e u r .ROUGE ; c2 = C o u l e u r . VIOLET ; i f ( c1 . compareTo ( c2 )== −1) System . o u t . p r i n t l n ( " c1 < c2 " ) ; else i f ( c1 . compareTo ( c2 ) = = 1 ) System . o u t . p r i n t l n ( " c1 > c2 " ) ; else System . o u t . p r i n t l n ( " c1 = c2 " ) ; 1.2 Valeur ordinale et nom JAVA associe à chaque élément du type énuméré une valeur ordinale, qui détermine l’ordre entre les éléments Méthode Description final int ordinal (); Retourne la valeur ordinale de l’élément f i n a l S t r i n g name ( ) ; Retourne la description, sous forme d’une chaîne de caractères, du nom exact utilisé pour identifier l’é 1.3 Tableau des valeurs possibles Il est possible de retrouver toutes les valeurs d’un type énuméré à l’aide de la méthode : static f i n a l NomEnumeration [ ] v a l u e s ( ) ; Ainsi, il est possible de passer à la valeur suivante (par une incrémentation de la valeur ordinale) comme suit : NomEnumeration e ; NomEnumeration s u i v a n t e = NomEnumeration . v a l u e s ( ) [ e . o r d i n a l ( ) + 1 ] ; / / I l f a u t f a i r e a t t e n t i o n a ne p a s d e p a s s e r l e s l i m i t e s du t a b l e a u ! Stéphane Cardon page 1/4 Exemple : Considérons l’énumération des quatre points cardinaux avec une méthode circulaire permettant de passer à la suivante dans le sens horaire et dans le sens anti-horaire. p u b l i c enum D i r e c t i o n { NORD, EST , SUD, OUEST ; public Direction horaire () { i n t v= o r d i n a l ( ) + 1 ; i f ( v== v a l u e s ( ) . l e n g t h ) v =0; return values ( ) [ v ] ; } public Direction antiHoraire () { i n t v= o r d i n a l ( ) − 1 ; i f ( v==−1) v= v a l u e s ( ) . l e n g t h −1; return values ( ) [ v ] ; } } 1.4 Utilisation dans un switch À l’aide de la valeur ordinale, il est possible d’utiliser une variable de type énuméré comme un entier dans un switch : Couleur c ; switch ( c ) { c a s e ROUGE: System . o u t . p r i n t l n ( "Du r o u g e ! " ) ; break ; ... } 1.5 Instantiation par une description La méthode statique de la classe Enum (dont hérite tout type énuméré) : p u b l i c s t a t i c Enum v a l u e O f ( C l a s s c l a s s e , String valeur ); Permet l’instantiation de l’élément sachant que : – le nom exact est valeur – le type de l’énumération est classe Exemple : C o u l e u r c=Enum . v a l u e O f ( C o u l e u r . c l a s s , "ROUGE" ) ; i f ( C o u l e u r .ROUGE . e q u a l s ( c ) ) System . o u t . p r i n t l n ( " C o u l e u r s i d e n t i q u e s " ) ; 1.6 Type énuméré et classe Un type énuméré est à peu prés semblable à une classe. Les seules instances possibles sont les éléments du type. Néanmoins, il est possible d’ajouter des constructeurs (private), des attributs et des méthodes. Exemple : Ajout d’informations sur les couleurs (une couleur est codée sur 24 bits) : – 8 bits pour son intensité en rouge : 0 à 255 – 8 bits pour son intensité en vert – 8 bits pour l’intensité bleue Possibilité d’indiquer s’il s’agit d’une couleur primaire ou non p u b l i c enum C o u l e u r { ROUGE( 2 5 5 , 0 , 0 , t r u e ) , JAUNE ( 2 5 5 , 2 5 5 , 0 , t r u e ) , BLEU( 0 , 0 , 2 5 5 , t r u e ) , Stéphane Cardon page 2/4 NOIR ( 0 , 0 , 0 , f a l s e ) , BLANC( 2 5 5 , 2 5 5 , 2 5 5 , f a l s e ) , ORANGE( 2 5 5 , 1 2 8 , 0 , f a l s e ) , MAGENTA( 2 5 5 , 0 , 2 5 5 , f a l s e ) , VERT( 0 , 2 5 5 , 0 , f a l s e ) ; p r i v a t e byte r , g , b ; p r i v a t e boolean primaire ; p r i v a t e Couleur ( byt e r , byt e g , byt e b , bool ean prim ) { th is . r=r ; t h i s . g=g ; t h i s . b=b ; p r i m a i r e =prim ; } public boolean e st Pr im a i re ( ) { return primaire ; } } 1.7 Conclusion Est-ce vraiment la bonne solution pour le concept de couleur ? NON ! L’utilisateur peut créer toute une panoplie de couleurs en faisant varier les intensités rouges, vertes et bleues. Exactement 243 possibilités. Le type énuméré s’utilise lorsqu’il n’y a qu’un nombre limité de valeurs possibles au concept et qu’elles sont définies à l’avance ! 2 Liste d’arguments variables Permet le passage de plusieurs valeurs en paramètre sans en connaître le nombre à l’avance : – Toutes les valeurs à partir du paramètre variable doivent être du même type. – Le dernier paramètre dans la signature de la méthode doit être l’argument variable 2.1 Syntaxe et utilisation Une méthode déclarée de la sorte : v o i d uneMethode ( i n t p a r a m F i x e , String . . . paramVariable ) ; Peut s’utiliser comme suit : uneMethode ( 3 , " b o n j o u r " , " t o u t " , " l e " , " monde " ) ; uneMethode ( 0 , " au " , " r e v o i r " , " ! " ) ; 2.2 Utilisation En fait le paramètre variable est considéré et transformé automatiquement comme un tableau : v o i d uneMethode ( i n t p a r a m F i x e , String . . . paramVariable ) { f o r ( i n t i = 0 ; i < p a r a m V a r i a b l e . l e n g t h ; i ++) System . o u t . p r i n t l n ( p a r a m V a r i a b l e [ i ] ) ; } Stéphane Cardon page 3/4 2.3 Exemple Imaginons vouloir implémenter une addition d’un nombre quelconque d’entiers : public s t a t i c i n t r e s =0; int additionner ( int . . . valeurs ) { f o r ( i n t i = 0 ; i < v a l e u r s . l e n g t h ; i ++) r e s += v a l e u r s [ i ] ; return res ; } 3 Simplifications syntaxiques Les notions qui suivent permettent une syntaxe plus lisible et plus intuitive. 3.1 Boucle itérative Permet de parcourir un tableau : int [] tableau ; f o r ( i n t uneValeur : t a b l e a u ) { / ∗ u n e V a l e u r va p r e n d r e l e s v a l e u r s du t a b l e a u une à une d a n s l ’ o r d r e d e s i n d i c e s ∗ / } Fonctionne aussi avec les paramètres variables : public s t a t i c i n t r e s =0; int additionner ( int . . . valeurs ) { for ( int v : valeurs ) r e s +=v ; } 3.2 Auto-boxing/Auto-unboxing Permet l’utilisation des objets représentant les types primitifs comme s’il s’agissait de variables primitives : – Auto-boxing : création automatique d’un objet représentant le type primitif avec la valeur primitive en paramètre : Float zero = 0 f ; / ∗ un o b j e t de t y p e F l o a t s e r a c r é é ∗ / /∗ Equivalent à : ∗/ F l o a t z e r o = new F l o a t ( 0 f ) ; – Auto-unboxing : récupération automatique de la valeur primitive encapsulée dans un objet de type primitif : f l o a t v = zero ; / ∗ v r e c e v r a l a v a l e u r e n c a p s u l é e dans l ’ o b j e t ∗/ /∗ Equivalent à : ∗/ f l o a t v = zero . floatValue ( ) ; Stéphane Cardon page 4/4