Почему Enum должен реализовывать интерфейс? - PullRequest
171 голосов
/ 25 апреля 2010

Я только что узнал, что Java позволяет перечислениям реализовывать интерфейс. Что было бы хорошим вариантом для этого?

Ответы [ 15 ]

2 голосов
/ 09 июня 2011

Перечисления похожи на Java-классы, они могут иметь конструкторы, методы и т. Д. Единственное, что вы не можете сделать с ними, это new EnumName(). Экземпляры предварительно определены в вашем объявлении enum.

1 голос
/ 06 ноября 2018

Пост выше, в котором упоминались стратегии, недостаточно затронул только то, что дает вам хорошая легкая реализация шаблона стратегии с использованием enums:

public enum Strategy {

  A {
    @Override
    void execute() {
      System.out.print("Executing strategy A");
    }
  },

  B {
    @Override
    void execute() {
      System.out.print("Executing strategy B");
    }
  };

  abstract void execute();
}

Вы можете хранить все свои стратегии в одном месте, не требуя отдельной единицы компиляции для каждой. Вы получаете хорошую динамическую отправку только с:

Strategy.valueOf("A").execute();

делает Java читаемым почти как хороший свободно напечатанный язык!

1 голос
/ 13 февраля 2018

Другая возможность:

public enum ConditionsToBeSatisfied implements Predicate<Number> {
    IS_NOT_NULL(Objects::nonNull, "Item is null"),
    IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
    IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");

    private final Predicate<Number> predicate;
    private final String notSatisfiedLogMessage;

    ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
        this.predicate = predicate;
        this.notSatisfiedLogMessage = notSatisfiedLogMessage;
    }

    @Override
    public boolean test(final Number item) {
        final boolean isNotValid = predicate.negate().test(item);

        if (isNotValid) {
            log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
        }

        return predicate.test(item);
    }
}

и использование:

Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
1 голос
/ 29 апреля 2013

Вот моя причина, почему ...

Я заполнил JavaFX ComboBox значениями Enum. У меня есть интерфейс Identifiable (указывающий один метод: идентифицировать), который позволяет мне указать, как любой объект идентифицирует себя с моим приложением для целей поиска. Этот интерфейс позволяет сканировать списки объектов любого типа (любое поле, которое объект может использовать для идентификации) на совпадение идентификаторов.

Я бы хотел найти совпадение для значения идентификатора в моем списке ComboBox. Чтобы использовать эту возможность в моем ComboBox, содержащем значения Enum, я должен иметь возможность реализовать интерфейс Identifiable в моем Enum (который, как это бывает, тривиально реализовать в случае Enum).

0 голосов
/ 15 ноября 2015

Я использовал внутреннее перечисление в интерфейсе, описывающем стратегию для сохранения контроля над экземпляром (каждая стратегия - Синглтон).

public interface VectorizeStrategy {

    /**
     * Keep instance control from here.
     * 
     * Concrete classes constructors should be package private.
     */
    enum ConcreteStrategy implements VectorizeStrategy {
        DEFAULT (new VectorizeImpl());

        private final VectorizeStrategy INSTANCE;

        ConcreteStrategy(VectorizeStrategy concreteStrategy) {
            INSTANCE = concreteStrategy;
        }

        @Override
        public VectorImageGridIntersections processImage(MarvinImage img) {
            return INSTANCE.processImage(img);
        }
    }

    /**
     * Should perform edge Detection in order to have lines, that can be vectorized.
     * 
     * @param img An Image suitable for edge detection.
     * 
     * @return the VectorImageGridIntersections representing img's vectors 
     * intersections with the grids.
     */
    VectorImageGridIntersections processImage(MarvinImage img);
}

Тот факт, что enum реализует стратегию, удобен для того, чтобы класс enum мог выступать в качестве прокси для своего вложенного экземпляра. который также реализует интерфейс.

это своего рода стратегия EnumProxy: P код кода выглядит следующим образом:

VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);

Если бы он не реализовал интерфейс, он был бы:

VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...