Перечисления в Java являются типами классов

Как уже объяснялось, перечисление в Java — это тип класса. Хотя вы не можете создать экземпляр enum с помощью операции new, в остальном перечисление обладает всеми возможностями, которые имеются у других классов. Тот факт, что enum определяет класс, придает такую мощь перечислениям Java, которой лишены перечисления в других языках. Например, вы можете предоставлять им конструкторы, добавлять переменные экземпляров и методы, и даже реализовывать интерфейсы.

Важно понимать, что каждая константа перечисления является объектом его типа перечисления. То есть, когда вы определяете конструктор для enum, он вызывается при каждом создании константы перечисления. Также каждая константа перечисления имеет свою собственную копию переменных экземпляра, объявленных перечислением. Например, рассмотрим следующую версию Apple.

// Использование конструктора enum, переменной экземпляра и метода.
enum Apple {
Jonathan(lO), GoldenDel(9), RedDel (12), Winesap(15), Cortland(8);
private int price; // цена каждого яблока
// Конструктор
Apple (int p) { price = p; }
int getPriceO { return price; }
}
class EnumDemo3 {
public static void main(String args[]) {
Apple ap;
// Отобразить цену Winesap.
System.out.println("Winesap стоит " + Apple.Winesap.getPrice() + " центов.\n");
// Отобразить цены всех сортов яблок.
System.out.println("Все цены яблок:");
for(Apple а : Apple.values())
System.out.println(a + " стоит " + a.getPrice() + " центов.");
}
}

Ниже показан вывод программы.

Winesap стоит 15 центов.
Все цены яблок:
Jonathan стоит 10 центов.
GoldenDel стоит 9 центов.
RedDel стоит 12 центов.
Winesap стоит 15 центов.
Cortland стоит 8 центов.

Данная версия Apple добавляет три вещи. Первая — это переменная экземпляра price, которая применяется для хранения цены каждого из сортов яблок. Вторая — конструктор Apple, которому передается цена яблок. Третий — метод getPrice (), возвращающий значение цены.

Когда в main () объявляется переменная ар, конструктор Apple вызывается однажды для каждой объявленной константы. Следует отметить, что аргументы конструктору передаются помещением их в скобки после каждой константы, как показано ниже:

Jonathan(10), GoldenDel(9), RedDel(12), Winesap(15), Cortland(8);

Эти переменные передаются параметру р конструктора Apple (), который затем присваивает их price. Опять же конструктор вызывается однажды для каждой из констант.

Поскольку каждая из констант перечисления имеет свою собственную копию price, вы можете получить цену определенного сорта яблок вызовом getPrice (). Например, в main () цена сорта Winesap получается следующим вызовом:

Apple.Winesap.getPrice ()

Цены всех сортов получаются в циклическом проходе по перечислению посредством цикла for. Поскольку существует копия price для каждой перечислимой константы, значение, ассоциированное одной константой, отделено и отличается от значения, ассоциированного с другой константой. Это мощная концепция, которая доступна только в случае реализации перечислений в виде классов, как это сделано в Java.

Хотя предыдущий пример содержит только один конструктор, enum может представлять две или более перегруженных формы, как это может делать любой другой класс. Например, приведенная ниже версия Apple предлагает конструктор по умолчанию, инициализирующий цену значением -1, означающим, что цена не указана.

// Использование конструкторов enum.
enum Apple {
Jonathan(10), GoldenDel(9), RedDel, Winesap(15), Cortland(8);
private int price; // цена каждого яблока
// Конструктор
Apple(int p) {
price = p; }
// Перегруженный конструктор
Apple () { price = -1; }
int getPrice() { return price; }
}

Обратите внимание, что в этой версии RedDel не передается аргумент. Это означает, что вызывается конструктор по умолчанию и переменная цены RedDel устанавливается равной -1.

Здесь есть два ограничения относительно перечислений. Во-первых, перечисление не может наследоваться от другого класса. Во-вторых, enum не может быть суперклассом. Это значит, что enum не может быть расширен. Во всем остальном enum ведет себя как любой другой тип класса. Ключевой момент — помнить, что каждая константа перечисления является объектом класса, в котором она определена.