JavaRush /Java Blog /Random EN /enum in java. Practical examples. Adding Constructors and...

enum in java. Practical examples. Adding Constructors and Methods

Published in the Random EN group
Hello! Today we will talk about a special data type in Java - Enum(short for enumeration). What is their feature? Let's imagine that we need to implement months in the program. Enum.  Practical examples.  Adding constructors and methods - 1It would seem, what is the problem? You just need to determine what properties any month has. Perhaps we need, first of all, the name of the month and the number of days in it. The solution to the problem looks quite 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 +
               '}';
   }
}
Full set please! We have a class Month, the necessary fields, getters-setters, toString(). Unless equals()you hashCode()need to add it for complete happiness :) However, we have a conceptual problem. As you may remember, one of the main advantages of OOP is that it makes it easy to model real-world entities. A chair, a car, a planet - all these concepts from everyday life are easy to represent in a program using abstraction. The problem is that some entities in the real world have a strictly limited range of meanings. There are only 4 seasons in a year. There are only 7 notes in music. There are only 12 months in the calendar. Ocean only has 11 friends (although this is debatable :)) In other words, a regular Java class is not able to model these entities and respect their natural constraints. Our class Monthhas all the necessary fields. But if another programmer uses it, no one will stop him from creating completely crazy objects:
public class Main {

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

}
If this appears in the program, it will not be easy to find the culprit! On the one hand, the programmer who created the objects could have understood that the class Monthmeant “month of the year” and not write such nonsense. On the other hand, he was just taking advantage of the opportunities that the class designer provided to him. Can I assign any names and number of days? He appointed it. What to do in such a situation? Before the release of the Java language version 1.5, programmers had to, frankly speaking, get out of it :) In those days, they created the following constructs:
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 +
               '}';
   }
}
Here we have simplified the number of months to three instead of twelve to keep the example shorter. Such designs made it possible to solve the problem. The options for created objects were limited by a private constructor:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Programmers using the class could not simply create Month. They were forced to use those final static objects that were provided by the class developer. It looked something like this:
public class Main {

   public static void main(String[] args) {

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

}
However, Java developers have noticed an existing problem. Of course, it’s great that programmers were able to come up with a solution using the tools available in the language, but it doesn’t look so simple! An obvious solution was needed, accessible even to beginners. This is how . appeared in Java Enum. Essentially, Enumit is a Java class that provides a limited set of value objects. Here's what it looks like:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
In the definition, we indicated that Enumthis is a Java class, but is this really so? Yes, and we can even check it. Try, for example, inheriting ours enum Monthfrom some other class:
public abstract class AbstractMonth {
}

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

   JANUARY,
   FEBRUARY,
   MARCH
}
Why is this happening? When we write to a program:
public enum Month
The compiler converts this command into code like this:
public Class Month extends Enum
As you already know, multiple inheritance is not allowed in Java. Therefore, AbstractMonthwe could not inherit from. How can this new design Enumbe used? And how is it different from the old design with static finalfields? Well, for example, the old design did not allow us to use our own set of values ​​in switch-expressions. Imagine that we want to create a program that will remind us what holidays are celebrated this month:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
Here, as you can see, the compiler throws an error. But after Java 1.5 appeared enum, everything became much simpler:
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);

   }

}
Console output:

7 января будет Рождество!
Please note: access to objects Enumremains static, as it was before Java 1.5. We don't need to create an object Monthto access months. When working with enumerations, it is very important not to forget that Enumthis is a full-fledged class. This means that, if necessary, you can define constructors and methods in it. For example, in the previous piece of code we simply specified the values ​​JANUARY, FEBRUARY, MARCH. However, we can expand ours enum Monthlike this:
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 +
               '}';
   }
}
Here we have added 2 fields to ours enum- the name of the month and the number of days, a constructor using these fields, getters-setters, a method toString(), as well as 2 static methods. As you can see, there were no problems with this: as we said earlier, enumthis is a full-fledged class:
import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

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

   }

}
Console output:

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
Finally, I want to recommend you one extremely useful book on Java, namely “Effective Java” by Joshua Bloch . Enum.  Practical examples.  Adding constructors and methods - 3The author is one of the creators of Java, so you can definitely trust his advice on the correct and competent use of language tools :) In relation to our lecture, I advise you to pay special attention to the chapter of the book dedicated to enum. Have a productive reading! :)
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION