JavaRush /Blog Java /Random-FR /Énumération en Java. Exemples pratiques. Ajout de constru...

Énumération en Java. Exemples pratiques. Ajout de constructeurs et de méthodes

Publié dans le groupe Random-FR
Bonjour! Aujourd'hui, nous allons parler d'un type de données spécial en Java - Enum(abréviation de énumération). Quelle est leur particularité ? Imaginons que nous devions mettre en œuvre des mois dans le programme. Énumération.  Exemples pratiques.  Ajout de constructeurs et de méthodes - 1Il semblerait, quel est le problème ? Il vous suffit de déterminer les propriétés d'un mois. Peut-être avons-nous besoin avant tout du nom du mois et du nombre de jours. La solution au problème semble assez simple :
public class Month {

   private String name;
   private int daysCount;

   public Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getDaysCount() {
       return daysCount;
   }

   public void setDaysCount(int daysCount) {
       this.daysCount = daysCount;
   }

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
Ensemble complet s'il vous plaît ! Nous avons une classe Month, les champs nécessaires, les getters-setters, toString(). A moins qu'il ne equals()soit hashCode()nécessaire de l'ajouter pour un bonheur complet :) Cependant, nous avons un problème conceptuel. Comme vous vous en souvenez peut-être, l'un des principaux avantages de la POO est qu'elle facilite la modélisation d'entités du monde réel. Une chaise, une voiture, une planète, tous ces concepts de la vie quotidienne sont faciles à représenter dans un programme utilisant l'abstraction. Le problème est que certaines entités du monde réel ont une gamme de significations strictement limitée. Il n'y a que 4 saisons par an. Il n'y a que 7 notes dans la musique. Il n'y a que 12 mois dans le calendrier. Ocean n'a que 11 amis (même si cela reste discutable :)) En d'autres termes, une classe Java classique n'est pas capable de modéliser ces entités et de respecter leurs contraintes naturelles. Notre classe Montha tous les champs nécessaires. Mais si un autre programmeur l'utilise, personne ne l'empêchera de créer des objets complètement fous :
public class Main {

   Month month1 = new Month("lolkek", 322);
   Month month2 = new Month("yahoooooooooooo", 12345);

}
Si cela apparaît dans le programme, il ne sera pas facile de trouver le coupable ! D’une part, le programmeur qui a créé les objets aurait pu comprendre que la classe Monthsignifiait « mois de l’année » et ne pas écrire de telles bêtises. D’un autre côté, il profitait simplement des opportunités que le concepteur de classe lui offrait. Puis-je attribuer des noms et un nombre de jours ? Il l'a nommé. Que faire dans une telle situation ? Avant la sortie du langage Java version 1.5, les programmeurs devaient, franchement, s'en sortir :) À cette époque, ils créaient les constructions suivantes :
public class Month {

   private String name;
   private int daysCount;

   private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public static Month JANUARY = new Month("Январь", 31);
   public static Month FEBRUARY = new Month("Февраль", 28);
   public static Month MARCH = new Month("Март", 31);

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
Ici, nous avons simplifié le nombre de mois à trois au lieu de douze pour garder l'exemple plus court. De telles conceptions ont permis de résoudre le problème. Les options pour les objets créés étaient limitées par un constructeur privé :
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Les programmeurs utilisant cette classe ne pouvaient pas simplement créer des fichiers Month. Ils ont été obligés d'utiliser les objets statiques finaux fournis par le développeur de la classe. Cela ressemblait à ceci :
public class Main {

   public static void main(String[] args) {

       Month january = Month.JANUARY;
       System.out.println(january);
   }

}
Cependant, les développeurs Java ont remarqué un problème existant. Bien sûr, c’est formidable que les programmeurs aient pu trouver une solution en utilisant les outils disponibles dans le langage, mais cela n’a pas l’air si simple ! Il fallait une solution évidente, accessible même aux débutants. C'est ainsi que .est apparu en Java Enum. Il s’agit essentiellement Enumd’une classe Java qui fournit un ensemble limité d’objets de valeur. Voici à quoi cela ressemble :
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
Dans la définition, nous avons indiqué qu’il Enums’agit d’une classe Java, mais est-ce vraiment vrai ? Oui, et nous pouvons même le vérifier. Essayez, par exemple, d'hériter du nôtre enum Monthd'une autre classe :
public abstract class AbstractMonth {
}

//ошибка! No extends clause allowed to enum
public enum Month extends AbstractMonth {

   JANUARY,
   FEBRUARY,
   MARCH
}
Pourquoi cela arrive-t-il? Quand on écrit dans un programme :
public enum Month
Le compilateur convertit cette commande en code comme ceci :
public Class Month extends Enum
Comme vous le savez déjà, l'héritage multiple n'est pas autorisé en Java. Nous ne pouvions donc AbstractMonthpas en hériter. Comment Enumutiliser ce nouveau design ? Et en quoi est-ce différent de l’ancien design avec static finaldes champs ? Eh bien, par exemple, l'ancienne conception ne nous permettait pas d'utiliser notre propre ensemble de valeurs dans switchles -expressions. Imaginez que nous souhaitions créer un programme qui nous rappellera quelles fêtes sont célébrées ce mois-ci :
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
Ici, comme vous pouvez le voir, le compilateur renvoie une erreur. Mais après l'apparition de Java 1.5 enum, tout est devenu beaucoup plus simple :
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           case JANUARY:
               System.out.println("7 января будет Рождество!");
               break;
           case FEBRUARY:
               System.out.println("В феврале празднуется День Защитника Отечества - 23 февраля!");
               break;
           case MARCH:
               System.out.println("В марте отмечается Всемирный Женский День - 8 марта!");
               break;
       }
   }
}



public class Main {

   public static void main(String[] args) {

       HolidayReminder reminder = new HolidayReminder();
       reminder.printHolidays(Month.JANUARY);

   }

}
Sortie de la console :

7 января будет Рождество!
Attention : l'accès aux objets Enumreste statique, comme avant Java 1.5. Nous n'avons pas besoin de créer un objet Monthpour accéder aux mois. Lorsqu'on travaille avec des énumérations, il est très important de ne pas oublier qu'il Enums'agit d'un cours à part entière. Cela signifie que, si nécessaire, vous pouvez y définir des constructeurs et des méthodes. Par exemple, dans le morceau de code précédent nous avons simplement spécifié les valeurs JANVIER, FÉVRIER, MARS. Cependant, nous pouvons étendre le nôtre enum Monthcomme ceci :
public enum Month {

   JANUARY("Январь", 31),
   FEBRUARY("Февраль", 28),
   MARCH("Март", 31),
   APRIL("Апрель", 30),
   MAY("Май", 31),
   JUNE("Июнь", 30),
   JULY("Июль", 31),
   AUGUST("Август", 31),
   SEPTEMBER("Сентябрь", 30),
   OCTOBER("Октябрь", 31),
   NOVEMBER("Ноябрь", 30),
   DECEMBER("Декабрь", 31);

   private String name;
   private int daysCount;

   Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }

   public static Month[] getWinterMonths() {

       return new Month[]{DECEMBER, JANUARY, FEBRUARY};
   }

   public static Month[] getSummerMonths() {

       return new Month[]{JUNE, JULY, AUGUST};
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getDaysCount() {
       return daysCount;
   }

   public void setDaysCount(int daysCount) {
       this.daysCount = daysCount;
   }

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
Ici nous avons ajouté 2 champs au nôtre enum- le nom du mois et le nombre de jours, un constructeur utilisant ces champs, des getters-setters, une méthode toString(), ainsi que 2 méthodes statiques. Comme vous pouvez le constater, cela n'a posé aucun problème : comme nous l'avons dit plus tôt, enumil s'agit d'un cours à part entière :
import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

       System.out.println(Arrays.toString(Month.getSummerMonths()));

   }

}
Sortie de la console :

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
Enfin, je souhaite vous recommander un livre extrêmement utile sur Java, à savoir « Effective Java » de Joshua Bloch . Énumération.  Exemples pratiques.  Ajout de constructeurs et de méthodes - 3L'auteur est l'un des créateurs de Java, vous pouvez donc certainement vous fier à ses conseils pour une utilisation correcte et compétente des outils linguistiques :) Par rapport à notre conférence, je vous conseille de porter une attention particulière au chapitre du livre dédié à enum. Bonne lecture productive ! :)
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION