¿Se pueden subclasificar las enumeraciones para agregar nuevos elementos?

Resuelto Mike asked hace 15 años • 15 respuestas

Quiero tomar una enumeración existente y agregarle más elementos de la siguiente manera:

enum A {a,b,c}

enum B extends A {d}

/*B is {a,b,c,d}*/

¿Es esto posible en Java?

Mike avatar Sep 12 '09 16:09 Mike
Aceptado

No, no puedes hacer esto en Java. Aparte de cualquier otra cosa, dpresumiblemente sería una instancia de A(dada la idea normal de "extiende"), pero los usuarios que solo lo sabían Ano lo sabrían, lo que anula el punto de que una enumeración sea un conjunto bien conocido de valores.

Si pudiera contarnos más sobre cómo desea utilizar esto, podríamos sugerirle soluciones alternativas.

Jon Skeet avatar Sep 12 '2009 09:09 Jon Skeet

Las enumeraciones representan una enumeración completa de valores posibles. Entonces la respuesta (inútil) es no.

Como ejemplo de un problema real, tomemos los días laborables, los días de fin de semana y, en conjunto, los días de la semana. Podríamos definir todos los días dentro de los días de la semana, pero entonces no podríamos representar propiedades especiales ni para los días laborables ni para los fines de semana.

Lo que podríamos hacer es tener tres tipos de enumeración con un mapeo entre días laborables/días de fin de semana y días de la semana.

public enum Weekday {
    MON, TUE, WED, THU, FRI;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum WeekendDay {
    SAT, SUN;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum DayOfWeek {
    MON, TUE, WED, THU, FRI, SAT, SUN;
}

Alternativamente, podríamos tener una interfaz abierta para el día de la semana:

interface Day {
    ...
}
public enum Weekday implements Day {
    MON, TUE, WED, THU, FRI;
}
public enum WeekendDay implements Day {
    SAT, SUN;
}

O podríamos combinar los dos enfoques:

interface Day {
    ...
}
public enum Weekday implements Day {
    MON, TUE, WED, THU, FRI;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum WeekendDay implements Day {
    SAT, SUN;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum DayOfWeek {
    MON, TUE, WED, THU, FRI, SAT, SUN;
    public Day toDay() { ... }
}
Tom Hawtin - tackline avatar Sep 12 '2009 11:09 Tom Hawtin - tackline

La solución recomendada para esto es el patrón de enumeración extensible .

Esto implica crear una interfaz y usarla donde actualmente usa la enumeración. Luego haga que la enumeración implemente la interfaz. Puede agregar más constantes agregando una enumeración/clase adicional que también amplía la interfaz. Aquí está la idea general:

public interface TrafficLights {
  public abstract String getColour();
}
public enum StandardTrafficLights implements TrafficLights {
  RED, YELLOW, GREEN;
  public String getColour() {
    return name();
  }
}
public enum WeirdTrafficLights implements TrafficLights {
  DOUBLE_RED;
  public String getColour() {
    return name();
  }
}

Tenga en cuenta que si desea algo así, TrafficLights.valueof(String)tendrá que implementarlo usted mismo.

JodaStephen avatar Sep 12 '2009 11:09 JodaStephen