Добавить в цитаты Настройки чтения

Страница 91 из 133

Результат выполнения данной программы выглядит следующим образом:Value of tp: AIRPLANEtp contains TRAIN.A train runs on rails.

Прежде чем переходить к рассмотрению следующей темы, необходимо сделать одно замечание. Имена констант в перечислении Transport указываются прописными буквами (например, одна из них называется CAR, а не саг). Но это требование не является обязательным. Не существует никаких ограничений на использование регистра символов в именах констант перечислимого типа. Но поскольку константы перечислимого типа, как правило, предназначены для замены переменных, объявленных как final, имена которых по традиции обозначаются прописными буквами, то и имена констант перечислимого типа, как правило, обозначаются прописными буквами. И хотя на этот счет имеются разные точки зрения, в примерах программ, представленных в этой книге, для констант перечислимого типа будут выбираться имена, обозначаемые прописными буквами.Перечисления в Java относятся к типам классов

Приведенные выше примеры демонстрируют создание и использование перечислений, но они не дают полного представления обо всех их возможностях. В отличие от других языков программирования перечисления в Java реализованы как типы классов. И хотя создать экземпляр объекта типа enum с помощью оператора new нельзя, во всем остальном перечисления ничем не отличаются от классов. Такой способ реализации перечислений наделяет их богатыми возможностями, принципиально недостижимыми в других языках. Это, в частности, позволяет определять конструкторы перечислений, добавлять в них переменные экземпляра, методы и даже создавать перечисления, реализующие интерфейсы.Методы values () и vaJueOf ()

У всех перечислений имеются два предопределенных метода: values () и valueOf ().

Ниже приведены общие формы их объявления.public static перечислимый_тип[] values()public static перечислимый_тип valueOf(String str)

Метод values () возвращает массив, содержащий константы перечислимого типа, а метод valueOf () — константу того же типа, значение которой соответствует символьной строке str, передаваемой этому методу в качестве параметра. В обоих чаях перечислимый_тип обозначает тип используемого перечисления. Так, если воспользоваться рассмотренным выше перечислением Transport, то при вызове метода Transport .valueOf ("TRAIN") будет возвращено значение TRAIN типа Transport. Ниже приведен пример программы, демонстрирующий применение методов values () и valueOf().// Применение встроенных в перечисление методов.// Перечисление разных видов транспорта,enum Transport {CAR, TRUCK, AIRPLANE, TRAIN, BOAT}class EnumDemo2 { public static void main(String args[]) { Transport tp; System.out.println("Here are all Transport constants"); // воспользоваться методом values() // Получение массива констант типа Transport. Transport allTransports[] = Transport.values(); for(Transport t : allTransports) System.out.println(t); System.out.println(); // воспользоваться методом valueOf() // Получение константы под названием AIRPLANE. tp = Transport.valueOf("AIRPLANE"); System.out.println("tp contains " + tp); }}

Выполнение этой программы дает следующий результат:Here are all Transport constantsCARTRUCKAIRPLANETRAINBOATtp contains AIRPLANE

Обратите внимание на то, что в данном примере программы для перебора массива констант, полученного с помощью метода values (), используется вариант for-each цикла for. Ради большей наглядности данного примера в его коде создается переменная allTransports, которой присваивается ссылка на массив констант перечислимого типа. Но делать это совсем не обязательно, а цикл for можно написать так, как показано ниже. В этом случае необходимость в дополнительной переменной allTransports отпадает.for(Transport t : Transport.values ()) System.out.println(t);

Обратите также внимание на то, что значение, соответствующее имени AIRPLANE, было получено в результате вызова метода valueOf ():tp = Transport.valueOf("AIRPLANE");



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

Следует иметь в виду, что каждая константа перечислимого типа является объектом этого же типа, а следовательно, в перечислении можно определить конструкторы, ввести методы и объявить переменные экземпляра. Если определить для объекта перечислимого типа enum конструктор, он будет вызываться при создании каждой константы этого типа. А каждая константа перечислимого типа позволяет вызвать любой метод, определенный в перечислении. И у каждой константы перечислимого типа имеется собственная копия любой переменной экземпляра, определенной в перечислении. Ниже приведен пример с новой версией перечисления Transport, демонстрирующий применение конструктора, переменной экземпляра и метода. Благодаря им появляется возможность определить обычную скорость передвижения различных транспортных средств.// Применение конструктора, переменной экземпляра и// метода в перечислении,enum Transport { // Обратите внимание на инициализирующие значения констант. CAR(65), TRUCK(55), AIRPLANE(600), TRAIN(70), BOAT(22); // Объявление переменной экземпляра. private int speed; // обычная скорость каждого транспортного средства // Объявление конструктора. Transport(int s) { speed = s; } // Определение метода. int getSpeed() { return speed; }}class EnumDemo3 { public static void main(String args[]) { Transport tp; // отобразить скорость самолета // Скорость определяется с помощью метода getSpeed(). System.out.println("Typical speed for an airplane is " + Transport.AIRPLANE.getSpeed() + " miles per hour.n"); // отобразить все виды транспорта и скорости их передвижения System.out.println("All Transport speeds: "); for(Transport t : Transport.values()) System.out.println(t + " typical speed is " + t.getSpeedO + " miles per hour."); }}

Выполнение этой программы дает следующий результат:Typical speed for an airplane is 600 miles per hour.All Transport speeds:CAR typical speed is 65 miles per hour.TRUCK typical speed is 55 miles per hour.AIRPLANE typical speed is 600 miles per hour.TRAIN typical speed is 70 miles per hour.BOAT typical speed is 22 miles per hour.

В эту версию перечисления Transport внесен ряд дополнений. Во-первых, появилась переменная экземпляра speed, используемая для хранения скорости передвижения каждого вида транспортных средств. Во-вторых, в перечисление Transport добавлен конструктор, которому передается значение скорости. И в-третьих, в это перечисление добавлен метод getSpeedO , возвращающий значение переменной speed, т.е. скорость передвижения конкретного транспортного средства.

Когда переменная tp объявляется в методе main (), конструктор Transport () автоматически вызывается для каждой указанной константы. Аргументы, передаваемые конструктору, указываются в скобках после имени константы, как показано ниже.CAR(65), TRUCK(55), AIRPLANE(600), TRAIN(70), BOAT(22);

Числовые значения, передаваемые конструктору Transport () в качестве параметра s, присваиваются переменной speed. Обратите также внимание на то, что список констант перечислимого типа завершается точкой с запятой. Последней в этом списке указана константа BOAT. Точка с запятой требуется в том случае, если, помимо констант, в перечислении присутствуют и другие члены.

У каждой константы перечислимого типа имеется собственная копия переменной speed, что дает возможность выяснить скорость передвижения конкретного транспортного средства, вызвав метод getSpeed (). Например, в методе main () скорость самолета определяется при следующем вызове:Transport.AIRPLANE.getSpeed()

Скорость каждого транспортного средства определяется путем перебора констант перечислимого типа в цикле for. А поскольку у каждой такой константы имеется своя копия переменной speed, то значения скорости, связанные с разными константами, отличаются друг от друга. Это довольно эффективный принцип организации перечислений, но он возможен только в том случае, если перечисления реализованы в виде классов, как это сделано в Java.