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?
Enum – це справжній клас з усіма можливостями, що випливають із цього. Наприклад, якщо поточної реалізації днів тижня тобі недостатньо, ти можеш додати в 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='Неділя'}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ