2013-07-23 44 views
5

Enum benzeri bir sınıf için bunu temel sınıf olarak kullanmanın en iyi yolu nedir? Getter yöntemlerini yeniden kodlamak zorunda kalmadan farklı beton türleri oluşturabilmek istiyorum.Java Enum Temel Sınıfları

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

Ve Tool.getNames() Aracı sınıfındaki tüm Öğe adlarının bir listesini döndürür.

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

Bunun mümkün olmadığını biliyorum, ancak bu duruma nasıl yaklaşabilirim? Her sınıfın üyelerine tıpkı bir enum gibi ulaşabilmeyi isterdim: Tool.Pickaxe.

+3

Bir ipucu: enums başka bir sınıfı genişletemez, ancak yine de bir arabirim uygulayabilirler. – skiwi

+1

Enums, 'Enum' sınıfını otomatik olarak genişletir. Bir dersi uzatamazlar. Bir arayüz kullan. – MathSquared

+0

Bir arabirimin uygulanması, her bir alt sınıfın yöntemlerini kodlamak zorunda olduğum anlamına gelir. Bunu bir şekilde önlemek istiyorum. –

cevap

4

Bunu kendiniz uygulamak zorundasınız, uygulamış olduğunuz davranışı genişletemezsiniz. bölüm biridir

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

, şimdi bir enum 'örneği' kendisi aracılığıyla getIds() ve getNames() erişmek istemiyorum: Bununla birlikte çeşitli yöntemler uygulamak, başka kendinizi, ya da kimse zorlayabilir ama onlara sınıf aracılığıyla statik işlev olarak erişmek istersiniz.

Umarım bu zaten size yeterince yardımcı olur, ancak tamamlanmış olmaktan çok uzaktır ve jeneriklerle daha basit yapmanın yolları olabilir, ancak enemlerin hiçbir şeyi uzatamayacağını anlarsınız.

1

Kısmen gidebilirsin.

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

} 

Burada yine de enum yapıcınızın alanları depolamanız gerekir, ancak yalnızca bir arabirimi uygulamanız gerekir. Ebeveyn sınıfı, daha sonra, tüm yapıtları, kurgu zamanında verilen bir Set üzerinde yapabilir.

Bu tekniği kesinlikle çok fazla kodu bir üst sınıfta taşımak için kullanabilirsiniz, ancak ne yazık ki hepsi değil.