Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumeration inheritance in Java?

Tags:

java

enums

I am doing astrophysical research. I wrote a package containing the classes Star, Band, and Datfile. I also have the enumerated type of BandName. Each star contains several Bands, each Band contains several Datfiles.

I have observational data for several galaxies. For each of these, I make a StarDatabase class (a HashMap of Stars) and a Main class.

The problem I'm having is with the enumerated type of BandName. So far, all of the data I have used has been in the I and V bands. Now I have data in J, H, and K bands. If I simply add J, H, and K to BandName, all of my loops that iterate over all of the items in BandName and do something are now broken.

Any ideas?

Edit: To sum up my problem, I want every package to have its own BandName enum that it can iterate through. But this doesn't work, because the methods in the Star package are expecting objects of type Star.BandName and I am providing objects of type IndividualPackage.BandName.

like image 485
rhombidodecahedron Avatar asked Aug 06 '10 21:08

rhombidodecahedron


People also ask

Can enum be inherited in Java?

As we have learned, we cannot inherit enum classes in Java. However, enum classes can implement interfaces.

What is an enumeration in Java?

An enumeration (enum for short) in Java is a special data type which contains a set of predefined constants. You'll usually use an enum when dealing with values that aren't required to change, like days of the week, seasons of the year, colors, and so on.

Can enums have inheritance?

Inheritance Is Not Allowed for Enums.

Why do we use enumeration in Java?

Enums are used when we know all possible values at compile time, such as choices on a menu, rounding modes, command-line flags, etc. It is not necessary that the set of constants in an enum type stay fixed for all time. A Java enumeration is a class type.


2 Answers

You can't inherit an enum from another enum, although you can have your enum implement an interface. The technical problem (that all enums implicitly extend java.lang.Enum, thus they can't extend another class, only implement additional interfaces) is no accident:

For the most part, extensibility of enums turns out to be a bad idea. It is confusing that elements of an extension type are instances of the base type and not vice versa. There is no good way to enumerate over all of the elements of a base type and its extension. Finally, extensibility would complicate many aspects of the design and implementation.

From Effective Java 2nd Edition, Item 34.

However, I don't fully understand your problem: haven't you used values() for iterating through your enum? Then you shouldn't worry about extending your enum with new values.

Please specify more clearly what "broken" is supposed to mean.

Update: so you need to have distinct sets of bands for different types of stars - this can be implemented using distinct enums extending a common interface, e.g.:

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 */ }
  ...
}

And you can use these by making your Star class generic:

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

This works nicely if the bands are organized into distinct groups. If there are stars with mixed band groups, however, you might prefer an alternative approach:

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}));
...

This allows you to set up stars with an arbitrary mix of bands. However, this way you can't use EnumSet or EnumMap on the bands.

like image 157
Péter Török Avatar answered Nov 01 '22 05:11

Péter Török


All enums implicitly extend java.lang.Enum. Since Java does not support multiple inheritance an enum cannot extend anything else. - http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

like image 1
Jordan Allan Avatar answered Nov 01 '22 04:11

Jordan Allan