Изменения
→Наследование в enum
==ПредисторияПредыстория==Программируя , мы часто сталкиваемся с необходимостью ограничить множество допустимых значений для некоторого типа данных. Так, например, день недели может иметь 7 разных значений, месяц в году - 12, а время года - 4. Для решения подобных задач во многих языках программирования со статической типизацией предусмотрен специальный тип данных - перечисление <tex>(enum)</tex>.Данный тип данных появился в Java начиная с версии 1.5. (enum) предоставляет множество удобств как в компактности записи, так и в удобстве использования. Так же, в отличие, допустим, от C, перечисления в Java представляют собой полноценные объекты, что предоставляет разработчику гораздо большую гибкость.
==Введение ==
<tex>— name()</tex> — имя константы в виде строки
<tex>— valueOf()</tex> — статический метод, позволяющий получить объект перечисления по классу и имени
===Итерация по enum===Рассмотрим пример, показывающий, как пройти по значениям любого перечислимого типа. public void PrintAll (PrintStream out) throws IOException { for (Unit u1 : Unit.values()) { for (Unit u2 : Unit.values()) { out.println(String.format("There are %f %sS in one %s",u2.getLength()/u1.getLength(), u1, u2)); } } } В результате выполнения которого чего мы получим следующий текст: There are 1 KILOMETER in one KILIMETER There are 0.001 KILOMETER in one METER There are 0.000001 KILOMETER in one MILLIMETER There are 1000 METER in one KILIMETER There are 1 METER in one METER There are 0.001 METER in one MILLIMETER There are 1000000 MILLIMETER in one KILIMETER There are 1000 MILLIMETER in one METER There are 1 MILLIMETER in one MILLIMETER Так же можно использовать следующую запись для вывода значений на консоль экран: System.out.println(Arrays.toString(Unit.values())); В результате будет выведено SUMMER: [KILOMETER, METER, MILLIMETER] ===Переключение с enum===Перечислимые типы очень удобно использовать для итерации и в операторах <tex>switch</tex>. Для сравнения значения unit с разными возможными мерами длин можно использовать следующую запись: unit.equals(Unit.METER) Но множество сравнений заняло бы много места.Для этого мы используем <tex>switch</tex>, в результате чего у нас получается следующая запись: switch (unit) { case KILOMETER: return "km"; case METER: return "m"; case MILLIMETER: return "mm"; } В результате чего он выдаст соответствующую меру длины. Так же можно употребить <tex>default</tex>, на тот случай, если вдруг другой программист добавил новые значения в Unit, а вас не предупредил. Поставив для варианта <tex>default</tex> вывод сообщения об отсутствии в списке значения unit, вы обнаружите это изменение. ===Получение элемента enum по строковому представлению его имени===Довольно часто возникает задача получить элемент enum по его строковому представлению. Для этих целей в каждом enum-классе компилятор автоматически создает специальный статический метод: public static EnumClass valueOf(String name), который возвращает элемент перечисления EnumClass с названием, равным name. Пример использования: String name = "METER"; Unit unit = Unit.valueOf(name); В результате чего в unit будет записано значение METER. ==Коллекции перечислимых типов== В Java использование generics в enum запрещено. Но можно использовать EnumMap и EnumSet. ===EnumSet===EnumSet - класс схожий с Set, и созданный для использования в нем элементов Enum классов. Естественно все эллементы находящиеся в EnumSet, должны быть из единственного перечислимого типа, который определяется, явно или неявно, когда набор создается. В EnumSet нулевые элементы не разрешаются, а попытки вставить нулевой элемент бросят Exception. Но, к сожалению, проверки на наличие нулевого элемента будут работать должным образом. Как и говорилось EnumSet очень схож с обычным Set, поэтому достаточно рассмотреть только примеры инициализации EnumSet: EnumSet<T> EnumSet.allOf(T.class) - создает EnumSet, содержащий все элементы из указанного класса. EnumSet<T> EnumSet.copyOf(Collection<T> t) - Создает EnumSet, содержащий все элементы находящиеся в колекции. EnumSet<T> EnumSet.copyOf(EnumSet<T> s) - Создает EnumSet содержащий те же элементы. EnumSet<T> EnumSet.complementOf(EnumSet<T> s) - Создает EnumSet с тем же типом данных как и у указанного EnumSet, но содержащий элементы не входящие в указанный набор. EnumSet<T> EnumSet.noneOf(T.class) - Создает пустой EnumSet, но сразу определяет для него тип используемых в нем данных в последующей работе с ним. EnumSet<T> EnumSet.of(e1, e2, e3...) - Создает EnumSet, первоначально содержащий указанные элементы. EnumSet<T> EnumSet.range(from, to) - Создает EnumSet, первоначально содержащий все элементы в диапазоне от первого указанного элемента до второго указанного элемента. ===EnumMap===EnumMap - это специализированный класс Map, для работы с Enum. В EnumMap все происходит аналогично. Все Эллементы должны быть из единственного перечислимого типа. Эллементы так же хранятся в их естественном порядке(порядок в котором хранятся элементы в Enum классе). И Так же не доступен нулевой эллемент, попытки вставить его бросят Exception. Рассмотрим примеры создания EnumMap : EnumMap<K,V>(K.class) - создает пустой EnumMap, и определяет для него тип хранящихся ключей. EnumMap<K,V>(EnumMap<K,V>) - создает EnumMap являющийся копией данного. EnumMap<K,V>(Map<K,V>) - создает EnumMap, инициализируемую по данной Map. ==Пример==Раньше класс бинарных операций мы записывали следующим образом:
public class BinaryOperation {
public class Plus {
}
}
public enum BinaryOperation {
Plus("+") {
}
abstract public int calculate(int a, int b);
}