Перечисление в Java - это класс, в частности подкласс Enum
, для которого объекты автоматически создаются и присваиваются именам, определенным во время компиляции.
- Перечисление может реализовывать интерфейс. Это означает, что каждый объект, созданный и названный в перечислении, предлагает этот метод.
- Можно сделать перечисление для хранения ссылки на объект интерфейса, причем эта ссылка является переменной-членом в каждом из его именованных экземпляров.
Давайте посмотрим на каждый из них.
Enum, реализующий интерфейс
Да, enum может реализовать интерфейс. Как и для любого другого класса, определите с помощью ключевого слова implements
и реализуйте необходимые методы.
Допустим, у нас есть интерфейс Animal
с одним методом speak
.
package work.basil.example;
public interface Animal
{
String speak();
}
Мы можем создать перечисление, реализующее этот интерфейс. Это означает, что все именованные объекты этого класса enum предлагают такое поведение.
package work.basil.example;
public enum GrannyPet implements Animal
{
// Enum objects, automatically instantiated when this class loads.
TWEETY(),
SYLVESTER(),
HECTOR();
@Override
public String speak ()
{
return "talk";
}
}
Давайте попробуем такое поведение, вызвав метод для каждого из экземпляров перечисления.
Set < GrannyPet > grannyPets = EnumSet.allOf( GrannyPet.class );
for ( GrannyPet grannyPet : grannyPets )
{
System.out.println( "Granny’s pet: " + grannyPet + " says: " + grannyPet.speak() );
}
Выход.
Домашнее животное бабушки: ТВИТИ говорит: говори
Домашнее животное бабушки: СИЛЬВЕСТ говорит: говори
Домашнее животное бабушки: Гектор говорит: говори
Но я не думаю, что это то, что вы имели в виду.
Перечисление, ссылающееся на объекты интерфейса
Я подозреваю, что вы хотите перечисление, каждый объект которого ссылается на объект определенного класса.
Да, мы можем это сделать. Перечисление в Java может иметь метод конструктора, и этот конструктор может принимать аргументы. Таким образом, мы можем передать объект вашего желаемого интерфейса в конструктор для каждого экземпляра объекта enum. Все это происходит автоматически при загрузке класса enum, как и для любого enum.
Animal
Давайте использовать тот же интерфейс, Animal
.
package work.basil.example;
public interface Animal
{
String speak();
}
Давайте определим три класса, реализующих этот интерфейс, Bird
, Cat
и Dog
.
Bird
package work.basil.example;
public class Bird implements Animal
{
@Override
public String speak ()
{
return "chirp";
}
}
Cat
package work.basil.example;
public class Cat implements Animal
{
@Override
public String speak ()
{
return "meow";
}
}
Dog
package work.basil.example;
public class Dog implements Animal
{
@Override
public String speak ()
{
return "bark";
}
}
GrannyPet
enum
Пересмотрите наш enum с конструктором, принимающим аргумент Animal
. Сохраните этот Animal
объект в переменной-члене.
Итак, перечисление GrannyPet
не реализует интерфейс Animal
, оно содержит объект типа Animal
.
Сравните этот код с перечисленным выше кодом перечисления, заметив, как TWEETY, SYLVESTER и HECTOR каждый из них принимают аргумент здесь, используя пустые пароли ()
выше. Итак, TWEETY()
против TWEETY( new Bird() )
.
package work.basil.example;
public enum GrannyPet
{
// Enum objects, automatically instantiated when this class loads.
TWEETY( new Bird() ),
SYLVESTER( new Cat() ),
HECTOR( new Dog() );
// Member variables.
private Animal animal;
// Constructor
GrannyPet ( Animal animalArg )
{
this.animal = animalArg;
}
// Accessor, getter.
public Animal getAnimal ()
{
return this.animal;
}
}
Наконец, мы пересматриваем наш код, вызывая перечисление из этого:
grannyPet.speak()
… на это:
grannyPet.getAnimal().speak()
Этот код вызова выглядит следующим образом:
Set < GrannyPet > grannyPets = EnumSet.allOf( GrannyPet.class );
for ( GrannyPet grannyPet : grannyPets )
{
System.out.println( "Granny’s pet: " + grannyPet + " says: " + grannyPet.getAnimal().speak() );
}
При запуске.
Домашнее животное бабушки: Твиттер говорит: щебетать
Домашнее животное бабушки: СИЛЬВЕСТ говорит: мяу
Домашнее животное бабушки: Гектор говорит: кора