2013-07-23 25 views
5

Qual è il modo migliore per utilizzarlo come classe base per una classe di tipo Enum. Mi piacerebbe essere in grado di creare diversi tipi di calcestruzzo senza dover ricodificare i metodi getter.Classi di base Enum in Java

public enum Tool extends Item 
{ 
    Pickaxe("Pickaxe", 101), 
    Saw("Saw", 201); 
} 

E Tool.getNames() restituirebbe un elenco di tutti i nomi di oggetto nella classe Strumento.

public enum Item 
{ 
    Default("Name", 0); 

    private final int id; 
    private final String name; 

    Item(String name, int id) 
    { 
     this.id = id; 
     this.name = name; 
    } 

    public int getId() 
    { 
     return this.id; 
    } 

    public int[] getIds() 
    { 
     Item[] items = Item.values(); 
     int[] ids = new int[items.length]; 
     for (int i = 0; i < items.length; i++) 
     { 
      ids[i] = items[i].getId(); 
     } 
     return ids; 
    } 

    public String getName() 
    { 
     return this.name; 
    } 

    public String[] getNames() 
    { 
     Item[] items = Item.values(); 
     String[] names = new String[items.length]; 
     for (int i = 0; i < items.length; i++) 
     { 
      names[i] = items[i].getName(); 
     } 
     return names; 
    } 
} 

So che non è possibile così, ma come potrei affrontare questa situazione? Mi piacerebbe poter accedere ai membri di ogni classe proprio come faresti con una enumerazione: Tool.Pickaxe.

+3

Un suggerimento: le enumerazioni non possono estendere un'altra classe, tuttavia possono ancora implementare un'interfaccia. – skiwi

+1

Le enumerazioni automagicamente estendono la classe 'Enum'. Non possono estendere una classe. Usa un'interfaccia. – MathSquared

+0

Implementare un'interfaccia significa che dovrò ancora codificare i metodi per ciascuna sottoclasse. Voglio evitare questo in qualche modo. –

risposta

4

È necessario implementarlo da soli, non è possibile estendere il comportamento già implementato. È tuttavia possibile forzare te stesso, o chiunque altro, per implementare i vari metodi:

public interface Item { 
    public int getId(); 
    public String getName(); 
} 

public enum Tool implements Item { 
    Pickaxe("Pickaxe", 101), 
    Saw("Saw", 201); 

    private final int id; 
    private final String name; 

    public Item(final String name, final int id) { 
     this.id = id; 
     this.name = name; 
    } 

    @Override 
    public int getId() { 
     return id; 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 
} 

che fa parte uno, ora non si vuole accedere alla getIds() e getNames() tramite un enum 'istanza' stessa , ma si desidera accedervi tramite la classe come funzione statica.

Spero che questo ti aiuti già abbastanza, ma è tutt'altro che completo e con i generici potrebbero esserci anche dei modi per farlo più semplice, ma capisci che le enumerazioni non possono estendere nulla.

1

Si può andare a metà percorso.

public class MyItem extends Item<MyItem.Items> { 
    public MyItem() { 
    // Tell my parent class about my enum. 
    super(EnumSet.allOf(Items.class)); 
    } 
    public enum Items implements Item.Items { 
    Pickaxe("Pickaxe", 101), 
    Saw("Saw", 201); 
    private final int id; 
    private final String name; 

    // You have to do these. 
    Items(String name, int id) { 
     this.id = id; 
     this.name = name; 
    } 

    @Override 
    public int getId() { 
     return this.id; 
    } 

    @Override 
    public String getName() { 
     return this.name; 
    } 

    } 
} 

// The parent class that does the common work. 
public class Item<I extends Enum<I> & Item.Items> { 
    // Keep track of the items. 
    private final Set<I> items; 

    // Pas a set of the items in the constructor. 
    public Item(Set<I> items) { 
    this.items = items; 
    } 

    // The interface. 
    public interface Items { 
    public int getId(); 

    public String getName(); 

    } 

    // Ready-made functionality. 
    public List<Integer> getIds() { 
    List<Integer> ids = new ArrayList<>(); 
    for (I i : items) { 
     ids.add(i.getId()); 
    } 
    return ids; 
    } 

    public List<String> getNames() { 
    List<String> names = new ArrayList<>(); 
    for (I i : items) { 
     names.add(i.getName()); 
    } 
    return names; 
    } 

} 

Qui si devono ancora avere il vostro enum negozio costruttore i campi, ma è solo bisogno di implementare un'interfaccia. La classe genitore può quindi eseguire tutto il lavoro su un Set che viene dato in fase di costruzione.

È possibile utilizzare questa tecnica per spostare molto del codice in una classe padre ma purtroppo non tutti.