Произвольный аргумент перечисления Java - PullRequest
2 голосов
/ 27 марта 2009

Я довольно новичок в Java, и я привык к тому, что перечисления по сути не более чем именованный список целых чисел.

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

Есть ли хороший способ заставить родительский класс принимать любое перечисление, определенное в его дочерних классах? Или мне придется написать собственный класс для этого?

Редактировать: Вот мой пример, исправленный в соответствии с ответом Джона Скитса, для всех, кто ищет, как это сделать позже:

class Parent {
   protected interface ParentEvent {}
   private HashMap<ParentEvent, String> actions = new HashMap<ParentEvent, String>();

   protected void doStuff(ParentEvent e){

      if(actions.containsKey(e)){
         System.out.println(actions.get(e));
      }

   }
}

class Child extends Parent {
   enum Event implements ParentEvent {EDITED, ADDED, REMOVED}

   public void trigger(){
      doStuff(Event.REMOVED);
   }
}

Ответы [ 4 ]

9 голосов
/ 27 марта 2009

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

Как вы говорите, перечисления в Java довольно разные. Они не именованные числа - это фиксированный набор значений, но эти значения являются объектно-ориентированными (то есть они могут использовать полиморфизм и т. Д.). Java перечисляет довольно много, за исключением нескольких хитрых проблем с порядком инициализации.

2 голосов
/ 27 марта 2009

Если я вас правильно понимаю, вы хотите иметь общий базовый класс для вашего перечисления и хотите определить несколько не связанных наборов перечислений для подклассов. Это невозможно с типами java типобезопасных, потому что они не позволяют вам определять базовый класс.

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

Для такого случая использования у меня довольно хороший опыт работы с Typesafe Enum Pattern Джоша Блоха, который он описывает в Effective Java

Просто представьте свой суперкласс здесь и создайте отдельные подклассы для каждого из значений enum, которые нужны вашим клиентским классам.

0 голосов
/ 27 марта 2009

Вы можете определить перечисления в их собственном файле, если они применимы к различным классам. Их не нужно вкладывать в класс.

Вы не можете расширить один набор перечислений от другого.

Мне потребовалось некоторое время, чтобы избавиться от мышления перечисления «просто быть целым числом».

0 голосов
/ 27 марта 2009

Я не уверен, но, возможно, это то, что вы хотите:

public abstract class EnumTest<E extends Enum<E>> {
  public abstract void frobnicate(E value);
}

public class Derived extends EnumTest<Derived.DerivedEnum> {
  public void frobnicate(DerivedEnum value) {
    System.out.println(value);
  }

  public static enum DerivedEnum {
    FOO, BAR,
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...