Classe Interne, Anonyme & Enumération



Documents pareils
Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Programmer en JAVA. par Tama

Héritage presque multiple en Java (1/2)

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Auto-évaluation Programmation en Java

Chapitre 10. Les interfaces Comparable et Comparator 1

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Une introduction à Java

Java Licence Professionnelle CISII,

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Initiation à JAVA et à la programmation objet.

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Java 1.5 : principales nouveautés

Cours 1: Java et les objets

Langage Java. Classe de première SI

Généralités sur le Langage Java et éléments syntaxiques.

Programmation par les Objets en Java

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

TP1 : Initiation à Java et Eclipse

Programmation en Java IUT GEII (MC-II1) 1

as Architecture des Systèmes d Information

Apprendre la Programmation Orientée Objet avec le langage Java (avec exercices pratiques et corrigés)

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

Plan du cours. Historique du langage Nouveautés de Java 7

Tp 1 correction. Structures de données (IF2)

Programmation Par Objets

4. Groupement d objets

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

ACTIVITÉ DE PROGRAMMATION

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Langage et Concepts de Programmation Objet. 1 Attributs et Méthodes d instance ou de classe. Travaux Dirigés no2

RMI le langage Java XII-1 JMF

Utilisation d objets : String et ArrayList

PROGRAMMATION PAR OBJETS

Package Java.util Classe générique

Environnements de développement (intégrés)

Chapitre VI- La validation de la composition.

Chapitre 2. Classes et objets

Traduction des Langages : Le Compilateur Micro Java

INITIATION AU LANGAGE JAVA

TD/TP PAC - Programmation n 3

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

Présentation. Au programme. Fonctionnement. A l issue de ce module vous devriez...

Facultés Universitaires Notre-Dame de la Paix. Conception et Programmation Orientées- Object

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Premiers Pas en Programmation Objet : les Classes et les Objets

Objets et Programmation. origine des langages orientés-objet

Java Licence professionnelle CISII,

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Projet de programmation (IK3) : TP n 1 Correction

Programmation avec des objets : Cours 7. Menu du jour

TD3: tableaux avancées, première classe et chaînes

Aide mémoire UML & Java 1ère partie : Introduction. marc.lemaire@u-cergy.fr

TP, première séquence d exercices.

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Bases Java - Eclipse / Netbeans

Support de cours et TD Programmation Orientée Objet

JADE : Java Agent DEvelopment framework. Laboratoire IBISC & Départ. GEII Université & IUT d Evry nadia.abchiche@ibisc.univ-evry.

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Machines virtuelles fonctionnelles (suite) Compilation ML Java

Programmation Orientée Objet en C#

Java Licence Professionnelle CISII,

Chapitre V. Les classes : Object, Vector, etc.

TD/TP PAC - Programmation n 3

JAVA TD0. Prise en main du langage Environnement de base JAVA 1

Programmation Objet Java Correction

Java c est quoi? Java pourquoi?

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Corrigé des exercices sur les références

2 e édition JAVA 5 et 6. Jérôme Bougeault. TSoft et Groupe Eyrolles, 2003, 2008, ISBN :

2. Comprendre les définitions de classes

Info0604 Programmation multi-threadée. Cours 5. Programmation multi-threadée en Java

Généralités. javadoc. Format des commentaires. Format des commentaires. Caractères spéciaux. Insérer du code

Application web de gestion de comptes en banques

7 Développement d une application de MapReduce

Bases du langage. Historique Applications et applets Éléments de base du langage Classes et objets Les exceptions

Génie Logiciel avec Ada. 4 février 2013

F. Barthélemy. 17 mai 2005

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Exercices sur les interfaces

1 Définition d une classe en Java

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Polycopié Cours Programmation Orientée Objet sous Java Programme : Filière SMI S5

Serveur d'archivage 2007 Installation et utilisation de la BD exist

Projet gestion d'objets dupliqués

Programmation Objet I

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

ALGORITHMIQUE ET PROGRAMMATION ORIENTEE OBJET

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Remote Method Invocation Les classes implémentant Serializable

Introduction à JDBC. Accès aux bases de données en Java

Programmation Orientée Objet application au langage Java Version Novembre 2007

Généricité. en Java. (polymorphisme paramétrique) Philippe GENOUD UJF Janvier

Transcription:

Java Avancé Classe Interne, Anonyme & Enumération Rémi Forax forax@univ-mlv.fr 1

Rappel Nous nous intéressons aujourd'hui à deux formes de type abstrait en Java Les interfaces Les classes abstraites Les classes internes, anonymes et les énumérations sont des types permettant de définir facilement des type concrets implantant ces types abstraits 2

Classe internes Il existe quatre sortes de classes internes : Les classes interne statique de classe Les inner-class de classe Les classes internes de méthode Les classes anonymes de méthode 3

Classe internes public class A { public static class B { Classe interne statique de classe public class A { public void m() { class B { Classe interne de méthode public class A { public class B { Inner-class de classe public class A { public void m() { new Object() {... ; Classe anonyme de méthode 4

Classe Interne Statique Classe interne qui n'a pas besoin d'un objet de la classe englobante pour exister. Classe utile pour cacher des détails d'implantation La différence avec une classe ordinaire est le scope ou elle est définie. public class Coords { private final Pair[] array; Visibilité de package public void add(int index,int x,int y) { array[index]=new Coords.Pair(x,y); static class Pair { private final int x,y;... 5

Rapport avec le C Une classe interne est complètement différente d'une sous-structure en C En C, les sous-structures sont toutes instanciées en même temps que la structure englobante, elles font partie de la structure En Java, les classes internes sont définies dans la classe englobante mais sont instanciées séparemment (comme une classe ordinaire). Dans le cas des Inner classe, les objets de la classes interne ont une référence sur une instance de la classe englobante. 6

Espace de nommage Le nom de la classe interne est ClassEnglobante.ClassInterne public class Coords { private final Pair[] array; public Pair add(int index,int x,int y) { return array[index]=new Pair(x,y); // return array[index]=new Coords.Pair(x,y); public static class Pair { private final int x,y;... public static void main(string[] args) { Coords coords=new Coords(10); Coords.Pair pair=coords.add(0,1,2); 7

Classe interne sur le disque Le compilateur génère deux classes différentes : Coords.class et Coords$Pair.class La machine virtuelle ne fait pas la différence entre une classe classique et une classe interne 8

Inner Class Une instance de Classe interne à besoin d'une instance de la classe englobante pour exister. public class Sequence { private final char[] array; public class Sub { // sub sequence of sequence private final int offset; private final int length; public char charat(int index) { if (index<0 index>=length) throw new IllegalArgumentException(...); return array[offset+index]; L' Inner Class peut accèder aux champs de l'objet. 9

Instantiation d'inner Class public class Sequence { private final char[] array; public Sequence(String s) { array=s.tochararray(); public class Sub { private final int offset; private final int length; public Sub(int offset,int length) { this.offset=offset; this.length=length; public char charat(int index) { return array[offset+index]; Instantiation d'une inner class Lors de la construction, une inner class doit être construite par un objet de la classe englobante Sequence s=new Sequence("toto"); Sub sub=s.new Sub(1,3); System.out.println(sub.charAt(0)); 10

Instantiation d'inner Class (2) A l'intérieur de la classe englobante, il n'est pas nécessaire de préfixé par this public class Sequence { private final char[] array; public class Sub { public Sub(int offset,int length) { public Sub subsequence(int offset) { return new Sub( offset,array.length-offset); // return this.new Sub(...) 11

Référence sur la classe englobante Pour obtenir une référence sur la classe englobante. public class Holder {... public void print() { System.out.println(this); public class Printer { public void print() { System.out.println(this); System.out.println(Holder.this); Holder Holder.this Printer référence: OuterClass.this 12

this et inner class Une inner-class possède une référence sur le this de sa classe englobante (ici Holder.this) Holder h1=new Holder(); System.out.println(h1); h1.print(); Holder.Printer p= h1.new Printer(); p.print(); public class Holder { public void print() { System.out.println(this); public class Printer { public void print() { System.out.println(this); System.out.println(Holder.this); 13

Génération par le compilateur Le compilateur ajoute un champs vers la classe englobante et change l'appel au constructeur Holder h1=new Holder(); System.out.println(h1); h1.print(); Holder$Printer p= new Holder$Printer(h1); p.print(); public class Holder { public void print() { System.out.println(this); public class Holder$Printer { private final Holder this$0; public Holder$Printer(Holder this$0) { this.this$0=this$0; public void print() { System.out.println(this); System.out.println(this$0); Code généré 14

Inner-class et membre statique Il est interdit de déclarer des membres statiques à l'intérieur d'une inner-class. public class A { public class B { static void m() { // illégal public class A { public class B { static void m() { // ok Il est possible de déclarer ce membre dans la classe englobante. 15

Inner class en résumé Une inner class est donc une façon raccourci d'écrire une classe ayant une référence sur une classe englobante avec en plus l'accès direct au champs de l'objet englobant. L'inner class à accès à l'ensemble des membres de la classes englobante (champs, méthode, autre classes internes) ce qui peut être syntaxiquement agréable. 16

Interface interne Il est possible de définir des interfaces à l'intérieurs de classe ou d'interface public class MyClass { public interface I { // interface interne statique public interface MyInterface { public class A { // classe interne statique Une interface interne est toujours statique Une classe interne d'interface est toujours statique 17

Visibilité Les classes internes et inner-class de classe ont une visibilité car ce sont des membres de la classe englobante Le constructeur par défaut de cette classe possède la même visibilité public class Coords { private static class Pair { // le compilateur génère un constructeur privé 18

Accès et visibilité Une classe englobante à accès à tous les membres de sa classe interne (même privés) Une classe interne statique à accès à tous les membres statique d'une classe englobante Une inner-class à accès à tous les membres d'une classe englobante 19

Exemple d'accès La classe englobante Coords à accès au champs privée de la classe interne statique Pair car ceux-ci sont déclarés entre l'accolade ouvrante et fermante de la classe englobante public class Coords { private final Pair[] array;... public int getx(int index) { return array[index].x; // accès à x private static class Pair { private final int x,y;... 20

Accès et visibilité Il n'y donc pas de private entre classe englobante et class interne Problème car pour la VM, les deux classes sont indépendantes Solution : Le compilateur génére des méthodes d'accès pour éviter les violations de visibilité. On parle d'accessseur synthétique. 21

Accesseurs générés La méthode synthétique permet access$0 d'accéder au champ privé x. public class Coords { private final Pair[] array; public int getx(int index) { return access$0(array[index]); Code généré class Pair { private final int x,y; static int access$0(pair pair) { return pair.x; $ javap -private -classpath classes Coords$Pair class Coords$Pair extends java.lang.object{ private final int x; private final int y; public Coords$Pair(int, int); static int access$0(coords$pair); 22

Accesseurs sur le constructeur Le compilateur génère aussi un accesseur pour les constructeurs (avec une astuce pour éviter le clash) public class Holder { public Printer createprinter() { return this.new Printer(); private class Printer { Code généré public class Holder { public Printer createprinter() { return new Holder$Printer(this, null); class Holder$Printer { private final Holder this$0; private Holder$Printer(Holder h) { this.this$0=h; super(); Holder$Printer(Holder h, Holder$Printer notused) { this(h); 23

Classe interne et accesseur La VM ne connait pas les classes internes : donc il y a génération par le compilateur de code supplémentaire (access$...) Inconvénients : Bytecode plus gros Code un peu plus lent (en fait, pas d'impact car VM effectue inlining) Conseil : éviter la génération d'accesseurs 24

Dans eclipse On peut régler le compilateur pour qu'il emette un warning dans ces cas 25

Classes anonymes Permet de déclarer une classe et de créer un objet de celle-ci en une expression. La classe anonyme est un sous-type d'une interface ou d'une classe abstraite ou concrète Syntaxe : Type var=new Type(param1,param2...) { //définition de membres //(méthode/champs/classe) ; 26

Classe Anonyme Il est possible d'implanter une interface sans donner de nom à la classe interface Filter { boolean accept(file file); public class Test { public File[] subdirectories(file directory) { directory.listfiles(new Filter() { public boolean accept(file file) { return file.isdirectory(); ); Ici, on crée un objet d'une classe implantant l'interface Filter 27

Classe anonyme de classe On crée une sous-classe de BinOp anonyme Visibilité par défaut public abstract class BinOp { public BinOp(int v1,int v2) { this.v1=v1; this.v2=v2; abstract int eval(); int v1,v2; public class OperationFactory { public static BinOp plus(int e1,int e2) { return new BinOp(e1,e2) { int eval() { return v1 + v2; ; 28

Variable locale et classe anonyme La valeur des variables locales constantes est disponible dans la classe anonyme (capture) interface Operation { int eval(); public class OperationFactory { public static Operation plus(int e1, int e2) { return new Operation() { @Override public int eval() { return e1 + e2; ; e1 et e2 ne sont pas modifiées après initialisation, ils sont effectivement final Pour pouvoir capturer la valeur d'une variable, celle-ci doit être effectivement final (Java8) ou déclarée final 29

Capture de variable locale Si une variable dont la valeur est capturé est modifié, le compilateur plante! interface Operation { int eval(); public class OperationFactory { public static Operation plus(int e1, int e2) { e1 = 0; // e1 is not effectively final return new Operation() { @Override public int eval() { return e1+e2; ; Les variables doivent être final (ou effectivement final) car le compilateur effectue une copie lors de la création de la classe anonyme 30

Variable locale et classe anonyme Le compilateur génère la classe correspondante Les variables locales sont recopiés dans des champs finaux! public class OperationFactory { public static Operation plus(int e1, int e2) { return new OperatorFactory$1(e1, e2); class OperationFactory$1 implements Operation { private final int e1; private final int e2; public OperatorFactory$1(int e1, int e2) { this.e1 = e1; this.e2 = e2; @Override public int eval() { return e1+e2; 31

Relation avec les lambdas Si on veut implanter une interface avec 1 seule méthode abstraite (fonctional interface) alors il vaut mieux utiliser une lambda @FunctionalInterface interface Operation { int eval(); public class OperationFactory { public static Operation plus(int e1, int e2) { return () -> e1 + e2; La capture marche de la même façon 32

Classe anonyme/inner-class Comme les inner-class, les classes anonymes ont accès à tous les champs de la classe englobante public class Sequence { private final char[] array; public int length() { return array.length; public int get(int index) { return array[index]; public Sequence suffix(final int offset) { return new Sequence() { public int length() { return array.length - offset; public int get(int index) { return array[offset + index]; ; 33

Classes anonymes & Limitation Au vu de la syntaxe, il est impossible de créer une classe anonyme : Implantant plusieurs interfaces Héritant d'une classe et implantant une ou plusieurs interfaces Dans ces cas, il est toujours possible de déclarer une classe interne à une méthode 34

Les classes internes de méthode La classe interne est définie dans une méthode (pas utilisée souvent!) public class Util { public static int getprice(final Item item) { class Product extends Item implements Fiscal { public Product() { this.name = item.getname(); public int price() { return StoreManager.getStoreByProduct(name).price(name); private final String name; return new Product().price(); 35

Classification interne statique de classe Modificateur de visibilité X X Inner-class de classe interne de méthode anonyme de méthode Accès à l'objet englobant Accès aux variables locales X X X oui oui Sous-type de plusieurs types X X X 36

Type énuméré Un type énuméré est un type définisant un nombre fini de valeurs de ce type Exemple: jeux de cartes, options de l'appel système open() En Java, les valeurs d'un type énuméré sont des objets (et pas des constantes entières comme en C). 37

Enum en Java vs C En C, un enum est un int En Java, un enum est un type La syntaxe de Java est retro-compatible avec celle du C : enum OpenOption {READ, WRITE, READ_WRITE En Java, un enum possède en plus, des constructeurs, méthodes, champs, classes internes, etc. 38

Valeur de l'énumération Les valeurs de l'énumération sont des champs public final static. Ils ont le type du type énuméré public enum Option { l, a, v... public static void apply(option... options) { for(option option:options) { if (option == Option.l) { // long option else { if (option == Option.a) { // all option else { //Option.v // verbose option 39

Switch On peut faire un switch sur les valeurs d'une l'énumération Attention, il ne faut pas qualifier (pas de '.') les valeurs dans les cases public static void apply(option... options) { for(option option:options) { switch(option) { case l: // case Option.l ne compile pas!! // long option break; case a: // all option Break; case v: // verbose option 40

Un type énuméré est un object Tous les types énumérés hérite de java.lang.enum Ils possèdes donc deux méthodes : int ordinal() qui renvoie leur position dans l'ordre de déclaration (à partir de zéro) String name() qui renvoie leur nom public enum Options { l, a, v... public static void main(string[] args) { assert Options.l.ordinal() == 0; assert Options.a.name().equals("a"); 41

Membres d'un type énuméré Un type énuméré possède des membres : méthodes, champs, classes internes Les valeurs et les membres sont séparés par un ';' Avoir des enums mutable est pas une bonne idée public enum Age { jeune, mure, agé, vieux, cadavérique; private int année; // argh un accent public static void main(string[] args) { Age.jeune.année = 20; Age.jeune.année = 1200; // argh mutable... 42

Enumération et champs static Les constructeurs ne peuvent accéder aux champs statiques (problème d'ordre d'initialisation) public enum MyColor { RED, GREEN, BLUE; static final HashMap<String,MyColor> map= new HashMap<String,Color>(); private MyColor() { map.put(name(), this); // si c'était possible // NullPointerException Utiliser un bloc static (qui sera exécuté après l'initialisation des champs de l'enum) 43

Enumération et champs static Les constructeurs ne peuvent accéder aux champs statiques (problème d'ordre d'initialisation) public enum MyColor { RED, GREEN, BLUE; static final HashMap<String,MyColor> map= new HashMap<String,Color>(); MyColor() { map.put(name(), this); // si c'était possible // NullPointerException Utiliser un bloc static (qui sera exécuté après l'initialisation des champs de l'enum) 44

Enumération et champs static Les constructeurs ne peuvent accéder aux champs statiques (problème d'ordre d'initialisation) public enum MyColor { RED, GREEN, BLUE; static final HashMap<String,MyColor> map; static { map = new HashMap<String,Color>(); MyColor() { map.put(name(), this); // si c'était possible // NullPointerException Utiliser un bloc static (qui sera exécuté après l'initialisation des champs de l'enum) 45

Enumération et champs static Utiliser un bloc static (qui sera exécuté après l'initialisation des champs de l'enum) initalisés en premier public enum MyColor { RED, GREEN, BLUE; static final HashMap<String,MyColor> map; // le code suivant est inutile comme la méthode valueof // existe (mais pour le fun) static { HashMap<String,Color> map = new HashMap<String,Color>(); for(mycolor m:values()) { map.put(m.getname(),m); MyColor.map = map; 46

Constructeur d'un type énuméré Un enum peut avoir des constructeurs Ils doivent être private ou de package Les parenthèses ne sont pas obligatoire pour appeler le constructeur sans paramètre public enum Age { jeune, autrejeune(), mure(40), agé(60), vieux(80), cadavérique(999); // les valeurs de ordinal restent 0,1,2,3,4,5 private final int année; private Age() { this(20); private Age(int année) { this.année = année; 47

Méthodes générées Tous les types énumérés possèdent aussi deux méthodes statiques générées par le compilateur TypeEnuméré[] values() renvoie une copie d'un tableau contenant toutes les valeurs de l'énumération dans l'ordre de déclaration TypeEnuméré valueof(string name) renvoie la valeur de l'énumération dont le nom est name ou lève une exception IllegalArgumentException. 48

Exemple d'utilisation import java.util.*; import static Option.*; // import static public class Main { public static void main(string[] args) { Set<Option> set = EnumSet.noneOf(Option.class); for(option opt:option.values()) { if (opt==a) { // ok, avec import static Collections.addAll(set, l, v); else set.add(opt); System.out.println(set); Attention values() renvoie la copie d'un tableau à chaque appel 49

Révision - import static Permet d'éviter : double r = Math.cos(Math.PI * theta); remplacé par import static java.lang.math.pi; import static java.lang.math.cos;... double r = cos(pi * theta); à utiliser avec parcimonie, uniquement si cela améliore la lisibilité du code 50

Exemple d'énumération public enum Option { l, a, v; public static Option getoption(string s) { if (s.length()!=2 s.charat(0)!='-') return null; return Option.valueOf(s.substring(1)); public static void main(string[] args) { for(string s:args) { Option option=getoption(s); if (option!=null) System.out.println(option.name()+':'+option.ordinal()); //java Option -a -v -l // a:1 v:2 l:0 51

Classe interne et enumération Une énumération ne peut être définie que dans un contexte statique donc pas possible dans une inner class ou dans une méthode public class Myclass { class Inner { enum Arg { // interdit toto void f() { enum Arg2 { // interdit toto 52

Enumération et java.lang.enum Les enums héritent de java.lang.enum La class Enum est paramétré Enum<E extends Enum<E>>, E est le type de l'énumération public enum Option { l, a, v; public static void main(string[] args) { Option opt1=option.l; Enum<Option> opt2=option.a; 53

Enumération et héritage Le compilateur garantit que seules les enum hérite de java.lang.enum. Une classe ne peut hériter de Enum Une classe ne peut hériter d'une enumération Une énumération ne peut hériter d'une classe public class A extends Enum { // erreur public class A extends Option { // erreur public enum Option extends A { // erreur public enum Option2 extends Option { // erreur 54

Valeur d'enum anonyme Il est possible d'ajouter du code spécifiqe à une valeur particulière d'un enum La syntaxe entre les { est la même que pour les classes anonymes public enum Option { l, a, v { @Override public String tostring() { return "hello v"; ; public static void main(string[] args) { System.out.println(Option.v); // hello v 55

Valeur d'enum anonyme Le compilateur génère une classe anonyme! Pour chaque comportement différent Noter que le constructeur n'est pas privé! Le code précédent correspond au pseudo-code-généré suivant: public class Option extends java.lang.enum { Option(int ordinal, String name) { super(ordinal, name); public static final Option l = new Option(0, "l"); public static final Option a = new Option(1, "a"); public static final Option v = new Option(2, "v") { @Override public String tostring() { return "hello v"; ; 56

Enumération et Initialisation Il n'est pas possible de déclarer un constructeur pour un champs spécifique d'une énumération public enum MyEnum { max { max() { // erreur, considérée comme // une méthode pas un constructeur int f() { // ok return 3;, min Les contraintes sont les mêmes que pour les classes anonymes 57

Methode non atteignable La valeur d'une enum anonyme est typé par le type énuméré public enum Option { l, a, v { void f() { // inatteignable ; dans l'exemple Option.v est de type Option, donc on ne peut pas appeler f(). 58

Enumération abstraite Une énumération peut être abstraite (mieux que le switch) public enum Option { l { public void performs() { System.out.println("long");, a { public void performs() { System.out.println("all");, v { public void performs() { System.out.println("verbose"); ; public static void performs(set<option> set) { for(option option:set) option.performs(); L'énumération ne doit pas être déclarée abstract!! public abstract void performs(); 59

Enumération et interface Une énumération peut donc implanter une ou plusieurs interfaces public interface Performer { public void performs(); public enum Option implements Performer { l { public void performs() { System.out.println("long");, a { public void performs() { System.out.println("all"); ; 60

Et avec des lambdas L'exemple précédent peut aussi utiliser la délégation public enum Option { l(() -> System.out.println("long")), a(() -> System.out.println("all")) ; interface Performer { public void performs(); private Performer performer private Option(Performer performer) { this.performer = performer; public void performs() { performer.performs(); 61

Enumération résumé Les énumération en Java ne sont pas des entiers mais des objets qui possède une méthode ordinal() On peut faire un switch dessus On peut ajouter des champs, des méthodes, des classes, etc, redéfinir des méthodes avec les enums abstraits Mais un enum représente un nombre fini de valeurs donc n'est pas un type extensible. 62