Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Герберт Шилдт. Java 2, v5.0 (Tiger). Новые возм...doc
Скачиваний:
5
Добавлен:
01.03.2025
Размер:
1.21 Mб
Скачать

Методы values() и valueOf()

Во все перечислимые типы автоматически включены два предопределенных метода: values () и vaiueOf(). Их синтаксическая запись приведена в следующих строках.

public static enum-tуре[] values()

public static enum-type valueOf(String str)

Метод values() возвращает массив, который содержит список констант перечислимого типа. Метод vaiueOf() возвращает перечислимую константу, значение которой соответствует содержимому строки, передаваемой в параметре str. В обоих случаях enum-typeперечислимый тип. В программе листинга 6.2 демонстрируется применение методов values() и valueOf().

Листинг 6.2. Применение встроенных методов перечислимого типа

enum Apple {

Jonathan, GoldenDel, RedDel, Winsap, Cortland

}

class EnumDemo2 {

public static void main(String args[])

{

Apple ap;

System.out.println("Here are all Apple constants");

// use values()

Apple allapples[] = Apple.values();

for(Apple a : allapples)

System.out.println(a);

System.out.println();

// use valueOf()

ap = Apple.valueOf("Winsap");

System.out.println("ap contains " + ap);

}

}

Далее приведен вывод результатов программы из листинга 6.2:

Here are all Apple constants

Jonathan

GoldenDel

RedDel

Winesap

Cortland

ap contains Winesap

Обратите внимание, в программе из листинга 6.2 используется цикл for в стиле for-each для обработки массива констант, полученного из метода values(). Для большей иллюстративности создана переменная allapples и ей присвоена ссылка на массив констант перечислимого типа. Но этот шаг необязателен, так как цикл for можно записать так, как показано в следующем фрагменте, и исключить необходимость применения переменной allapples:

for(Apple a ; Apple, values())

System.out.println(a);

Теперь посмотрим, как значение, соответствующее имени Winesap, получается с помощью вызова метода valueOf ().

ар = Apple.valueOf("Winsap");

Как уже объяснялось, метод valueOf() возвращает значение, связанное с именем константы, представленной в виде строки.

Замечание.

Как могут отметить программисты, пишущие на C/C++, в языке Java гораздо легче, чем в других языках, выполнять переходы между понятной человеку формой представления константы перечислимого типа и ее бинарной формой представления. Это существенное преимущество реализации перечислимого типа, принятой в языке Java.

Перечислимый тип в Java — это класс

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

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

Листинг 6.3. Использование конструктора, поля и метода в перечислимом типе

enum Apple {

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

private int price; // price of each apple

// Constructor

Apple(int p) { price = p; }

int getPrice() { return price; }

}

class EnumDemo3 {

public static void main(String args[])

{

Apple ap;

// Display price of Winsap.

System.out.println("Winsap costs " +

Apple.Winsap.getPrice() +

" cents.\n");

// Display all apples and prices.

System.out.println("All apple prices:");

for(Apple a : Apple.values())

System.out.println(a + " costs " + a.getPrice() +

" cents.");

}

}

Далее приведен вывод результатов программы из листинга 6.3:

Winesap costs 15 cents.

All apple prices:

Jonathan costs 10 cents.

GoldenDel costs 9 cents.

RedDel costs 12 cents.

Winesap costs 15 cents.

Cortland costs 8 cents.

Приведенная в листинге 6.3 версия класса Apple содержит следующие добавления.

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

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

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

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

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

Apple.Winsap.getPrice()

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

Несмотря на то, что в листинге 6.3 приведен один конструктор, перечислимый тип может предложить две или несколько перегруженных форм, как любой другой класс. В листинге 6.4 приведена версия класса Apple, предоставляющая конструктор по умолчанию (без аргументов) (default constructor), присваивающий цене значение, равное —1 для обозначения отсутствия сведений о цене.

Листинг 6.4. Использование конструктора типа enum

enum Apple {

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

private int price; // price of each apple

// Constructor

Apple(int p) { price = p; }

// Overloaded constructor

Apple() { price = -1; }

int getPrice() { return price; }

}

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

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