Enum'ы
Дорогу осилит идущийВАЖНО: ниже находится устаревшая версия статьи. Актуальную можно найти здесь: ссылка.
В этом уроке мы немного отвлечемся от ООП и познакомимся с функционалом, который предоставляет Java для перечисляемых типов — enum'ов.
Предлагаю ознакомиться со статьей: https://metanit.com/java/tutorial/3.8.php
И видео:
Также рекомендую для лучшего понимания, как реализован enum в Java, посмотреть еще одно:
Enum, проводя аналогии, может показаться гибридом констант и реализации наследования, где каждая константа — отдельный класс наследник. О том, так ли это на самом деле, рассказывает видео выше.
Обычно enum'ы используются для хранения информации, которая неизменна, но имеет большее влияние на систему, нежели константы. Например, часто через enum'ы реализуют различные статусы или состояния. Это удобно по двум причинам:
- Нет необходимости валидировать значение. В отличии от числовой или строковой константы, переменная/поле enum-типа примет только значение, указанное как один из элементов enum'а;
- Enum'ы могут содержать поля, что позволяет хранить для каждого значения его реальное название/описание или другую полезную информацию.
Как можно было заметить из статьи или видео, любой enum имеет набор характерных методов. Отметим те, которые действительно могут быть полезны (и один, о котором просто принято рассказывать новичкам):
- valueOf() — позволяет получить значение (элемент) enum'а по его строковому эквиваленту. Недоступен при обращении к элементу enum'а;
- values() — возвращает массив со всеми значениями enum'а, для которого был вызван. Недоступен при обращении к элементу enum'а;
- name() — метод, противоположный valueOf(). Возвращает название элемента в виде строкового значения. Доступен только при обращении к элементу enum'а;
- ordinal() — возвращает порядковый номер элемента enum'а. Практически не используется. Не рекомендую завязывать на нем какую-то логику. При добавлении нового элемента в начало или середину enum'а, порядковый номер элементов сдвинется. Зависимая логика может сломаться. Доступен только при обращении к элементу enum'а.
Еще несколько методов мы рассматривать не будем, поскольку они не популярны на практике, а у нас, в любом случае, не хватает знаний для работы с ними.
Также для элементов enum'а, как и любого другого объекта, доступны методы Object. Мы пока знакомы только с equals(). Но enum'ы также допустимо сравнивать через оператор ==.
Стоит обратить внимание на несколько нюансов при использовании enum'ов:
- В enum'е допустимо хранить поля. Каждое поле стоит помечать как final. Изменять значения полей enum'а — плохая практика;
- Мы можем описать методы для enum'а. Как общие для всего enum'а, так и с отдельной реализацией для каждого элемента. Первое допустимо и часто используется, второе — плохая практика, поскольку дает enum'у слишком большую зону ответственности, а код делает трудночитаемым;
- На начальном этапе может казаться, что enum'ы — хорошая альтернатива наследованию. Это не так. Enum'ы в Java имеют широкую функциональность, но и большие ограничения. На простых примерах использование enum'ов будет проще, чем полноценная реализация наследования с использованием полиморфизма (мы сравним в практической части), при реализации сложной логики — скорее всего, enum'ы создадут больше проблем;
- Enum'ы, как и другие классы, должны иметь четко очерченную зону ответственности. Не делайте их слишком тяжелыми;
- Каждый enum необходимо создавать в своем файле. Как классы и интерфейсы;
- Стиль нейминга для элементов enum'ов может зависеть от проекта. Я рекомендую использовать тот же подход, что и для констант уровня класса.
С теорией на сегодня все!

Переходим к практике:
Задача 1:
Реализуйте задачу https://github.com/KFalcon2022/practical-tasks/blob/master/src/com/walking/lesson3_casts_conditional_constructions/Task2SwitchCase.java
через enum. В т.ч. реализуйте в enum'е поиск значения по фразе, введенной пользователем. Напоминаю, что enum'ы могут содержать поля.
Задача 2:
Реализуйте задачу https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson14_polymorphism/task2
через enum. Пусть Cow, Dog и Cat будут значениями enum'а Animal.
Задача 3:
Реализуйте задачу https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson14_polymorphism/task1
через enum. Пусть EquilateralTriangle и Square будут значениями enum'а EquilateralShape.
Примечание: практика направлена на то, чтобы познакомиться с функционалом enum'ов в живую. Не все из этого стоит повторять на реальных проектах. Если реализации первой и второй задачи (по крайней мере, предполагаемые автором) допустимы в ряде случаев, то третья явно не должна реализовываться с помощью enum и ее решение через наследование и полиморфизм — наиболее канонично.
Подводя итог, основное назначение enum'ов — константы на максималках. Типы (чего угодно), статусы, состояния. Все то, что должно иметь конечное количество неизменяемых значений.
Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
Канал: https://t.me/+relA0-qlUYAxZjI6
Мой тг: https://t.me/ironicMotherfucker
Дорогу осилит идущий!