public class DayOfWeek {
private String title;
public DayOfWeek(String title) {
this.title = title;
}
public static void main(String[] args) {
DayOfWeek dayOfWeek = new DayOfWeek("Суббота");
System.out.println(dayOfWeek);
}
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
И вроде бы все хорошо, но есть одна проблема: в конструктор класса DayOfWeek можно передать любой текст. Таким образом, кто-то сможет создать день недели «Лягушка», «Облачко» или «azaza322». Это явно не то поведение, которое мы ожидаем, ведь реальных дней недели существует всего 7, и у каждого из них есть название.
Поэтому наша задача — как-то ограничить круг возможных значений для класса «день недели».
До появления Java 1.5 разработчики были вынуждены самостоятельно придумывать решение этой проблемы, поскольку готового решения в самом языке не существовало.
В те времена, если ситуация требовала ограниченного числа значений, делали так:
public class DayOfWeek {
private String title;
private DayOfWeek(String title) {
this.title = title;
}
public static DayOfWeek SUNDAY = new DayOfWeek("Воскресенье");
public static DayOfWeek MONDAY = new DayOfWeek("Понедельник");
public static DayOfWeek TUESDAY = new DayOfWeek("Вторник");
public static DayOfWeek WEDNESDAY = new DayOfWeek("Среда");
public static DayOfWeek THURSDAY = new DayOfWeek("Четверг");
public static DayOfWeek FRIDAY = new DayOfWeek("Пятница");
public static DayOfWeek SATURDAY = new DayOfWeek("Суббота");
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
На что тут стоит обратить внимание:
Приватный конструктор. Если конструктор помечен модификатором private, объект класса нельзя создать с помощью этого конструктора. А поскольку в этом классе конструктор всего один, объект DayOfWeek нельзя создать вообще.
public class Main { public static void main(String[] args) { DayOfWeek sunday = new DayOfWeek();//ошибка! } }
При этом в классе содержалось нужное количество public static объектов, которые были инициализированы нужным нам образом (названия дней правильные).
Это позволяло использовать объекты в других классах.
public class Man { public static void main(String[] args) { DayOfWeek sunday = DayOfWeek.SUNDAY; System.out.println(sunday); } }
Вывод:
DayOfWeek{title='Воскресенье'}
Что такое enum?
Итак, что же из себя представляет Enum в Java? Давай посмотрим на примере того же DayOfWeek:
public enum DayOfWeek {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
Выглядит уже намного проще :)
Внутри нашего Enum находятся 7 констант со статическим доступом. Мы уже можем его использовать для реализации логики в программе.
Например, напишем программу, которая будет определять, нужно ли школьнику сегодня идти на учебу. У нашего школьника будет свой режим дня, обозначенный классом ScholarSchedule:
public class ScholarSchedule {
private DayOfWeek dayOfWeek;
//...другие поля
public DayOfWeek getDayOfWeek() {
return dayOfWeek;
}
public void setDayOfWeek(DayOfWeek dayOfWeek) {
this.dayOfWeek = dayOfWeek;
}
}
Переменная dayOfWeek в режиме дня определяет, какой сегодня день.
А вот класс нашего школьника:
public class Scholar {
private ScholarSchedule schedule;
private boolean goToSchool;
public void wakeUp() {
if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
System.out.println("Ура, можно поспать еще!");
} else {
System.out.println("Блин, опять в школу:(");
}
}
}
В методе wakeUp() при помощи Enum определяем дальнейшие действия школьника.
Мы даже не описывали подробно, что значит каждая переменная в DayOfWeek, да это и не нужно: механизм дней недели и так очевиден, и если мы будем его использовать в текущем виде, любому разработчику будет понятно, что происходит в твоем коде.
Еще один пример удобства Enum: его константы можно использовать с оператором switch. Например, мы пишем программу для строгой диеты, в которой блюда расписаны по дням:
public class VeryStrictDiet {
public void takeLunch(DayOfWeek dayOfWeek) {
switch (dayOfWeek) {
case SUNDAY:
System.out.println("Воскресный обед! Сегодня можно даже немного сладкого");
break;
case MONDAY:
System.out.println("Обед для понедельника: куриная лапша!");
break;
case TUESDAY:
System.out.println("Вторник, сегодня суп из сельдерея :(");
break;
//...и так далее до конца
}
}
}
Это одно из преимуществ Enum перед старым решением, которое применялось до Java 1.5: старое решение нельзя было использовать со switch.Что еще нужно знать об Enum class?
Enum class — это настоящий класс со всеми вытекающими из этого возможностями. Например, если текущей реализации дней недели тебе недостаточно, ты можешь добавить в DayOfWeek переменные, конструкторы и методы:
public enum DayOfWeek {
SUNDAY ("Воскресенье"),
MONDAY ("Понедельник"),
TUESDAY ("Вторник"),
WEDNESDAY ("Среда"),
THURSDAY ("Четверг"),
FRIDAY ("Пятница"),
SATURDAY ("Суббота");
private String title;
DayOfWeek(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
Теперь у констант нашего Enum есть поле title, геттер и переопределенный метод toString.
По сравнению с обычными классами, на Enum наложили одно серьезное ограничение — от него невозможно наследоваться.
Кроме того, у перечислений есть характерные только для них методы:
values(): возвращает массив из всех хранящихся в Enum значений:
public static void main(String[] args) { System.out.println(Arrays.toString(DayOfWeek.values())); }
Вывод:
[DayOfWeek{title='Воскресенье'}, DayOfWeek{title='Понедельник'}, DayOfWeek{title='Вторник'}, DayOfWeek{title='Среда'}, DayOfWeek{title='Четверг'}, DayOfWeek{title='Пятница'}, DayOfWeek{title='Суббота'}]
ordinal(): возвращает порядковый номер константы. Отсчет начинается с нуля:
public static void main(String[] args) { int sundayIndex = DayOfWeek.SUNDAY.ordinal(); System.out.println(sundayIndex); }
Вывод:
0
- valueOf(): возвращает объект Enum, соответствующий переданному имени:
public static void main(String[] args) { DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY"); System.out.println(sunday); }
Вывод:
DayOfWeek{title='Воскресенье'}
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ