Могу ли я использовать интерфейс в качестве переменной в перечислении? - PullRequest
1 голос
/ 26 июня 2019

Я пытаюсь использовать интерфейс в качестве переменной в перечислении:

Пример интерфейса


public interface TestInterface {

void printMessage();

}

Класс, реализующий интерфейс


public class TestClass implements Test {

 @Override
    public void printMessage() {

        System.out.println("This is a test");

    }

}

Тогда у нас есть перечисление

public enum TestEnum {

TEST1(TestClass);

private final TestInterface interface;

TestEnum(TestInterface interface) {
   this.interface = interface;
}

}

Просто быстрый пример. Я пытаюсь что-то подобное, и это не позволяет мне использовать класс, реализующий интерфейс, в качестве значения в перечислении. Я искал в Google и не могу найти что-нибудь по этому вопросу.

Мне вообще разрешено это делать? Насколько я понимаю, я могу использовать класс, поскольку он реализует интерфейс? Что-то еще мне не хватает?

1 Ответ

0 голосов
/ 26 июня 2019

Перечисление в 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() );
    }

При запуске.

Домашнее животное бабушки: Твиттер говорит: щебетать

Домашнее животное бабушки: СИЛЬВЕСТ говорит: мяу

Домашнее животное бабушки: Гектор говорит: кора

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...