¿Se pueden subclasificar las enumeraciones para agregar nuevos elementos?
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?
No, no puedes hacer esto en Java. Aparte de cualquier otra cosa, d
presumiblemente sería una instancia de A
(dada la idea normal de "extiende"), pero los usuarios que solo lo sabían A
no 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.
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() { ... }
}
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.