Je veux prendre une énumération existante et ajouter plus d'éléments comme suit:
enum A {a,b,c}
enum B extends A {d}
/*B is {a,b,c,d}*/
Est-ce possible en Java?
Je veux prendre une énumération existante et ajouter plus d'éléments comme suit:
enum A {a,b,c}
enum B extends A {d}
/*B is {a,b,c,d}*/
Est-ce possible en Java?
Non, vous ne pouvez pas le faire en Java. Mis à part toute autre chose, d
serait alors probablement une instance de A
(étant donné l'idée normale de "extends"), mais les utilisateurs qui connaissaient seulement A
Je ne le saurais pas - ce qui va à l'encontre d'un enum étant un ensemble de valeurs bien connues.
Si vous pouviez nous en dire plus sur la façon dont vous voulez utiliser cela, nous pourrions potentiellement suggérer des solutions alternatives.
Les Enums représentent une énumération complète de valeurs possibles. Si l' (inutile) la réponse est non.
Comme un exemple réel d'un problème de prendre des jours de la semaine, week-end et jours, l'union, les jours de la semaine. On pourrait définir tous les jours dans les jours de la semaine, mais alors nous ne serions pas en mesure de représenter les propriétés spéciales, soit les jours de la semaine et week-end-jours.
Ce que nous pourrions faire, c'est avoir trois types enum avec un mappage entre les jours de la semaine/week-end-jours et des jours de la semaine.
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;
}
Alternativement, nous pourrions avoir une interface pour le jour de la semaine:
interface Day {
...
}
public enum Weekday implements Day {
MON, TUE, WED, THU, FRI;
}
public enum WeekendDay implements Day {
SAT, SUN;
}
Ou on peut aussi combiner les deux approches:
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 solution recommandée pour cela est le modèle enum extensible .
Cela implique de créer une interface et de l'utiliser lorsque vous utilisez actuellement l'énumération. Ensuite, faites enum enumérer l'interface. Vous pouvez ajouter plus de constantes en faisant en sorte que cette nouvelle énumération étende également l'interface.
Sous les couvertures de votre ENUM est juste une classe ordinaire généré par le compilateur. Qui a généré classe étend java.lang.Enum
. La technique de la raison pour laquelle vous ne pouvez pas étendre la classe générée, c'est que la classe générée est - final
. Les raisons conceptuelles pour qu'il soit final sont présentées dans cette rubrique. Mais je vais ajouter de la mécanique à la discussion.
Voici un test enum:
public enum TEST {
ONE, TWO, THREE;
}
Le code résultant de javap:
public final class TEST extends java.lang.Enum<TEST> {
public static final TEST ONE;
public static final TEST TWO;
public static final TEST THREE;
static {};
public static TEST[] values();
public static TEST valueOf(java.lang.String);
}
En théorie, vous pouvez taper cette classe sur votre propre et laissez tomber le "final". Mais le compilateur ne vous empêche de l'extension "la java.lang.Enum" directement. Vous pourriez décider de ne PAS prolonger java.lang.Enum, mais alors votre classe et ses classes dérivées ne serait pas un instanceof java.lang.Enum ... qui pourrait ne pas vraiment d'importance pour vous de toute façon!
enum A {a,b,c}
enum B extends A {d}
/*B is {a,b,c,d}*/
peut être écrite comme:
public enum All {
a (ClassGroup.A,ClassGroup.B),
b (ClassGroup.A,ClassGroup.B),
c (ClassGroup.A,ClassGroup.B),
d (ClassGroup.B)
...
Comment cela peut-être utile: disons que nous voulons quelque chose comme: Nous avons événements et nous utilisons des enums. Ces énumérations peuvent être regroupées par un traitement similaire. Si nous avons avec de nombreux éléments, certains événements se met en marche, certains sont tout simplement l'étape et de l'autre extrémité de l'opération. Pour recueillir ce type d'opération et d'éviter les longues commutateur cas, on peut les regrouper comme dans l'exemple et l'utilisation:
if(myEvent.is(State_StatusGroup.START)) makeNewOperationObject()..
if(myEnum.is(State_StatusGroup.STEP)) makeSomeSeriousChanges()..
if(myEnum.is(State_StatusGroup.FINISH)) closeTransactionOrSomething()..
Exemple:
public enum AtmOperationStatus {
STARTED_BY_SERVER (State_StatusGroup.START),
SUCCESS (State_StatusGroup.FINISH),
FAIL_TOKEN_TIMEOUT (State_StatusGroup.FAIL,
State_StatusGroup.FINISH),
FAIL_NOT_COMPLETE (State_StatusGroup.FAIL,
State_StatusGroup.STEP),
FAIL_UNKNOWN (State_StatusGroup.FAIL,
State_StatusGroup.FINISH),
(...)
private AtmOperationStatus(StatusGroupInterface ... pList){
for (StatusGroupInterface group : pList){
group.addMember(this);
}
}
public boolean is(StatusGroupInterface with){
for (AtmOperationStatus eT : with.getMembers()){
if( eT .equals(this)) return true;
}
return false;
}
// Each group must implement this interface
private interface StatusGroupInterface{
EnumSet<AtmOperationStatus> getMembers();
void addMember(AtmOperationStatus pE);
}
// DEFINING GROUPS
public enum State_StatusGroup implements StatusGroupInterface{
START, STEP, FAIL, FINISH;
private List<AtmOperationStatus> members = new LinkedList<AtmOperationStatus>();
@Override
public EnumSet<AtmOperationStatus> getMembers() {
return EnumSet.copyOf(members);
}
@Override
public void addMember(AtmOperationStatus pE) {
members.add(pE);
}
static { // forcing initiation of dependent enum
try {
Class.forName(AtmOperationStatus.class.getName());
} catch (ClassNotFoundException ex) {
throw new RuntimeException("Class AtmEventType not found", ex);
}
}
}
}
//Some use of upper code:
if (p.getStatus().is(AtmOperationStatus.State_StatusGroup.FINISH)) {
//do something
}else if (p.getStatus().is(AtmOperationStatus.State_StatusGroup.START)) {
//do something
}
Ajouter un peu plus avancé:
public enum AtmEventType {
USER_DEPOSIT (Status_EventsGroup.WITH_STATUS,
Authorization_EventsGroup.USER_AUTHORIZED,
ChangedMoneyAccountState_EventsGroup.CHANGED,
OperationType_EventsGroup.DEPOSIT,
ApplyTo_EventsGroup.CHANNEL),
SERVICE_DEPOSIT (Status_EventsGroup.WITH_STATUS,
Authorization_EventsGroup.TERMINAL_AUTHORIZATION,
ChangedMoneyAccountState_EventsGroup.CHANGED,
OperationType_EventsGroup.DEPOSIT,
ApplyTo_EventsGroup.CHANNEL),
DEVICE_MALFUNCTION (Status_EventsGroup.WITHOUT_STATUS,
Authorization_EventsGroup.TERMINAL_AUTHORIZATION,
ChangedMoneyAccountState_EventsGroup.DID_NOT_CHANGED,
ApplyTo_EventsGroup.DEVICE),
CONFIGURATION_4_C_CHANGED(Status_EventsGroup.WITHOUT_STATUS,
ApplyTo_EventsGroup.TERMINAL,
ChangedMoneyAccountState_EventsGroup.DID_NOT_CHANGED),
(...)
Au-dessus, si nous avons d'autres pas (myEvent.est(State_StatusGroup.L'ÉCHEC)) puis en itérant par les événements précédents, nous pouvons facilement vérifier si nous devons revenir de transfert d'argent par:
if(myEvent2.is(ChangedMoneyAccountState_EventsGroup.CHANGED)) rollBack()..
Il peut être utile pour:
- y compris explicite des méta-données sur le traitement de la logique, à moins de se rappeler
- la mise en œuvre de certains de multi-héritage
- nous ne voulons pas utiliser les structures de classe, ex. pour l'envoi de courts messages d'état
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.