2010-04-14 5 views
2

Je voudrais savoir s'il est possible en Java d'imbriquer Enums.Comment imbriquer un Enum dans la valeur d'un Enum

Voici ce que je voudrais être en mesure de le faire:

Avoir une espèce ENUM en chat et de chien Wich me donner accès à des sous énumérations des races de chats et de chiens disponibles. Par exemple, j'aimerais pouvoir tester si un CHAT ou un CHIEN et si un animal est un CHAT PERSAN ou un CHIEN PITBULL. Les races CAT et DOG doivent être des enums distincts, c'est-à-dire une énumération de CatBreeds et une énumération de DogBreeds.

Voici un exemple de modèle d'accès que je voudrais utiliser:

Espèce:

  • Species.CAT
  • Species.DOG

Races:

  • Espèces.CAT.breeds.PERSAN
  • Species.DOG.breeds.PITBULL
+0

Pour être un plus précis, je dois gérer différents type d'élément (ce qui est mon 1er ENUM dimnension). Un objet a un attribut et une carte Détail. La deuxième dimension enum peut être utilisée pour définir la clé de détail de la carte pour un type donné d'élément. – Mathieu

Répondre

3

Ne serait-vous mieux faire avec l'héritage? Le chat et le chien seraient des sous-classes d'espèces. Persion serait une sous-classe de Cat et Pitbull serait une sous-classe de Dog. Qu'est-ce que vous essayez d'obtenir en voulant utiliser Enums?

+0

J'ai seulement 2 classes, et n'ai pas besoin des autres. L'utilisation de l'héritage est un peu trop verbeuse et m'empêche d'utiliser la sélection de critères basée sur "type" ou la sélection de critères "type et sous-type". – Mathieu

+1

Il y a] à la fin de votre lien. Comprendre le mot de sélection en tant que filtrage. – Mathieu

+0

Merci Mathieu. Commentaire corrigé: Eh bien, si la sélection de critères basée sur "type" est ce que je pense, cela peut être une odeur de code. Voir http://hanuska.blogspot.com/2006/08/swich-statement-code-smell-and.html –

-1
public enum A { 

    a1, 
    a2; 

    public enum B { 
     b1, 
     b2 
    } 
} 

et ainsi de suite ...

+2

Neat - c'est un enum imbriqué et il pourrait être le meilleur qu'il obtient. Cependant, cela donne "Species.breeds.PERSAN" au lieu de "Species.CAT.breeds.PERSAN" qu'il veut. –

0

une façon de nid énumérations:

package nested2; 
import java.util.*; 
interface HasChildren { 
    Set<Enum<? extends HasChildren>> children(); 
    Class parent(); 
    Enum<? extends HasChildren> p(); 
} 
enum Citrus implements HasChildren { 
    lemon, lime, orange; 
    Enum<? extends HasChildren> p; 
    Class parent = getDeclaringClass(); 
    Class children; 
    public Enum<? extends HasChildren> p() { 
     return p; 
    } 
    public Class parent() { 
     return parent; 
    } 
    public Set<Enum<? extends HasChildren>> children() { 
     return children != null ? EnumSet.allOf(children) : null; 
    } 
    enum Orange implements HasChildren { 
     navel, valencia, blood; 
     Enum p; 
     Class parent = getDeclaringClass(); 
     Class children; 
     public Enum<? extends HasChildren> p() { 
      return p; 
     } 
     public Class<Enum<? extends HasChildren>> parent() { 
      return parent; 
     } 
     public Set<Enum<? extends HasChildren>> children() { 
      return children != null ? EnumSet.allOf(children) : null; 
     } 
     enum Navel implements HasChildren { 
      washinton, lateLane, caraCaraPink; 
      Enum<? extends HasChildren> p; 
      Class parent = getDeclaringClass(); 
      Class children; 
      public Enum<? extends HasChildren> p() { 
       return p; 
      } 
      public Class parent() { 
       return parent; 
      } 
      public Set<Enum<? extends HasChildren>> children() { 
       return null; 
      } 
     } 
     static { 
      navel.children = Navel.class; 
      for (Navel n : Navel.values()) 
       n.p = orange; 
      navel.p = navel; 
     } 
     enum Blood implements HasChildren { 
      moro, taroco; 
      Enum<? extends HasChildren> p; 
      Class parent = getDeclaringClass(); 
      Class children; 
      public Enum<? extends HasChildren> p() { 
       return p; 
      } 
      public Class parent() { 
       return parent; 
      } 
      public Set<Enum<? extends HasChildren>> children() { 
       return null; 
      } 
     } 
     static { 
      blood.children = Blood.class; 
      for (Blood b : Blood.values()) 
       b.p = blood; 
      blood.p = orange; 
     } 
    } 
    static { 
     for (Orange o : Orange.values()) 
      o.p = orange; 
     orange.children = Orange.class; 
    } 
} 
public class EnumTree { 
    static void visit(Class<?> clazz) { 
     Object[] enumConstants = clazz.getEnumConstants(); 
     if (enumConstants[0] instanceof HasChildren) for (Object o : enumConstants) 
      visit((HasChildren) o, clazz.getName()); 
    } 
    static void visit(HasChildren hasChildren, String prefix) { 
     if (hasChildren instanceof Enum) { 
      System.out.println(prefix + ' ' + hasChildren + " (" + hasChildren.parent() + ")" + " (" + hasChildren.p() 
        + " " + ((Enum) hasChildren).getDeclaringClass()); 
      if (hasChildren.children() != null) for (Object o : hasChildren.children()) 
       visit((HasChildren) o, prefix + ' ' + hasChildren); 
     } else 
      System.out.println("other " + hasChildren.getClass()); 
    } 
    static <E extends Enum<E> & HasChildren> Set<E> foo() { 
     return null; 
    } 
    public static void main(String[] args) { 
     //looks like p is the right parent 
     System.out.println(Citrus.Orange.Navel.washinton); 
     System.out.println(Citrus.Orange.Navel.washinton.getClass().getDeclaredClasses()); 
     System.out.println(Citrus.Orange.Navel.washinton.getClass().getEnclosingClass()); 
     System.out.println(Citrus.Orange.Navel.washinton.getClass().getDeclaringClass()); 
     visit(Citrus.lemon, ""); 
     System.out.println("----------------------"); 
     visit(Citrus.orange, ""); 
     System.out.println("----------------------"); 
     visit(Citrus.class); 
     System.out.println("----------------------"); 
    } 
}