2013-07-23 14 views
5

Jaki jest najlepszy sposób użycia tego jako klasy bazowej dla klasy podobnej do Enum. Chciałbym móc tworzyć różne typy betonu bez konieczności ponownego kodowania metod pobierających.Wydziel klasy bazowe w języku Java

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

Narzędzie Tool.getNames() zwróci listę wszystkich nazw elementów w klasie Tool.

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; 
    } 
} 

Wiem, że nie jest to możliwe, ale jak mogę podejść do tej sytuacji? Chciałbym móc uzyskać dostęp do członków każdej klasy, tak jak wy to wyliczacie: Tool.Pickaxe.

+3

Jedna podpowiedź: wyliczenia nie mogą rozszerzyć innej klasy, ale nadal mogą implementować interfejs. – skiwi

+1

Emulatory automagicznie rozszerzają klasę "Enum". Nie mogą rozszerzyć klasy. Użyj interfejsu. – MathSquared

+0

Implementacja interfejsu oznacza, że ​​nadal będę musiał kodować metody dla każdej podklasy. Chcę tego jakoś uniknąć. –

Odpowiedz

4

Będziesz musiał to zaimplementować samodzielnie, nie możesz rozszerzyć już zaimplementowanego zachowania. Można jednak zmusić się, ani nikogo innego, do wdrożenia różnych metod:

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; 
    } 
} 

To jest część pierwsza, teraz nie chcesz, aby uzyskać dostęp getIds() i getNames() poprzez wyliczenia „instancji” Sam , ale chcesz uzyskać do nich dostęp poprzez klasę jako funkcję statyczną.

Mam nadzieję, że to już wystarczająco pomaga, ale jest ono dalekie od ukończenia, a w przypadku leków generycznych mogą być nawet sposoby na uproszczenie, ale zrozum, że wyliczenia nie mogą niczego przedłużyć.

1

Możesz przejść w niepełnym miejscu.

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; 
    } 

} 

Tu trzeba jeszcze mieć swój sklep konstruktora enum pola ale wystarczy zaimplementować interfejs. Klasa nadrzędna może następnie wykonać całą pracę na zestawie podanym w czasie konstruowania.

Oczywiście można użyć tej techniki, aby przenieść wiele kodu poza klasę rodziców, ale niestety nie wszystkie.

Powiązane problemy