Java中的枚举基类

时间:2013-07-23 20:43:03

标签: java enums subclass

将此作为Enum like类的基类使用的最佳方法是什么。我希望能够创建不同的具体类型,而无需重新编写getter方法。

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

Tool.getNames()将返回Tool类中所有Item名称的列表。

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

我知道不可能这样,但我怎么能处理这种情况呢?我希望能够像访问枚举一样访问每个类的成员:Tool.Pickaxe。

2 个答案:

答案 0 :(得分:4)

您必须自己实现,不能扩展已实现的行为。但是,您可以强迫自己或其他任何人实施各种方法:

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

这是第一部分,现在您不想通过枚举“实例”本身访问getIds()getNames(),但您希望通过类作为静态函数访问它们。

我希望这对你有足够的帮助,但它远非完整,而且泛型甚至可能有更简单的方法,但是要明白枚举不能扩展。

答案 1 :(得分:1)

你可以分道扬。

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

}

在这里,您仍然必须让您的枚举构造函数存储字段,但您只需要实现一个接口。然后,父类可以在构造时给出的Set上完成所有工作。

你当然可以使用这种技术将很多代码移出父类,但遗憾的是并非全部。