Перечисление наследования в Java? - PullRequest
5 голосов
/ 07 августа 2010

Я занимаюсь астрофизическими исследованиями.Я написал пакет, содержащий классы Star, Band и Datfile.У меня также есть перечислимый тип BandName.Каждая звезда содержит несколько полос, каждая полоса содержит несколько файлов данных.

У меня есть данные наблюдений для нескольких галактик.Для каждого из них я создаю класс StarDatabase (HashMap of Stars) и класс Main.

Проблема, с которой я сталкиваюсь, связана с перечисляемым типом BandName.Пока что все данные, которые я использовал, были в I и V диапазонах.Теперь у меня есть данные в диапазонах J, H и K.Если я просто добавлю J, H и K в BandName, все мои циклы, которые перебирают все элементы в BandName и что-то делают, теперь не работают.Подводя итог моей проблеме, я хочу, чтобы у каждого пакета было собственное перечисление BandName, через которое он может проходить.Но это не работает, потому что методы в пакете Star ожидают объекты типа Star.BandName, а я предоставляю объекты типа IndividualPackage.BandName.

Ответы [ 3 ]

19 голосов
/ 07 августа 2010

Вы не можете наследовать перечисление от другого перечисления, хотя вы можете сделать так, чтобы ваше перечисление реализовало интерфейс.Техническая проблема (все перечисления неявно расширяют java.lang.Enum, поэтому они не могут расширять другой класс, реализуют только дополнительные интерфейсы) не случайна:

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

Из Effective Java 2nd Edition , Item 34.

Однако я не полностьюПонимаете вашу проблему: разве вы не использовали values() для перебора вашего перечисления?Тогда вам не нужно беспокоиться о расширении вашего перечисления новыми значениями.

Пожалуйста, уточните, что означает "сломанный".

Обновление: , так что вам нужноиметь разные наборы полос для разных типов звезд - это можно реализовать с помощью различных перечислений, расширяющих общий интерфейс, например:

interface Band {
  String getName();
  void doStuff();
  ...
}

enum BandsVI implements Band {
  V, I;
  public String getName() { return toString(); }
  public void doStuff() { /* do stuff as appropriate for these bands */ }
  ...
}

enum BandsJHK implements Band {
  J, H, K;
  public String getName() { return toString(); }
  public void doStuff() { /* do stuff as appropriate for these bands */ }
  ...
}

И вы можете использовать их, сделав свой класс Star универсальным:

class Star<T extends Enum<T> & Band> {
  private Class<T> bandType;
  public Star(Class<T> bandType) { this.bandType = bandType; }
  public void printBandNames() {
    for (Band b : bandType.getEnumConstants())
      System.out.println(b.getName());
  }
  public void doStuffOnAllBands() {
    for (Band b : bandType.getEnumConstants())
      b.doStuff();
  }
}
...
Star<BandsVI> star1 = new Star<BandsVI>(BandsVI.class);
Star<BandsJHK> star2 = new Star<BandsJHK>(BandsJHK.class);
star1.printBandNames(); // prints V I
star2.printBandNames(); // prints J H K

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

class Star {
  private List<? extends Band> bandTypes;
  public Star(List<? extends Band> bandTypes) { this.bandTypes = bandTypes; }
  public void printBandNames() {
    for (Band b : bandTypes)
      System.out.println(b.getName());
  }
  ...
}

...
Star star1 = new Star(Arrays.asList(BandsVI.values()));
Star star3 = new Star(Arrays.asList(new Band[]{BandsVI.V, BandsVI.I, BandsJHK.K}));
...

Это позволяет вам создавать звезды с произвольным смешением полос.Тем не менее, таким образом вы не можете использовать EnumSet или EnumMap на диапазонах.

1 голос
/ 07 августа 2010

Вот что я бы сделал (псевдокод):

class Band
{
     String name;
};
static Band J("J");
static Band K("K");

static ArrayList<Band> JK;
static ArrayList<Band> IHL;

class Star
{
    Star(ArrayList<Band> bands)
}

Таким образом, вы можете добавлять полосы, просто создавая больше объектов Band.Каждое начало имеет список полос, которые он использует, так что он может перебирать все их.

1 голос
/ 07 августа 2010

Все перечисления неявно расширяют java.lang.Enum.Поскольку Java не поддерживает множественное наследование, перечисление не может расширять что-либо еще.- http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

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