6

将其用作 Enum 类的基类的最佳方法是什么。我希望能够创建不同的具体类型,而不必重新编码 getter 方法。

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

Tool.getNames() 将返回 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;
    }
}

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

4

2 回答 2

5

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

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(),但您想通过类作为静态函数访问它们。

我希望这已经对你有足够的帮助了,但它远非完整,使用泛型甚至可能有更简单的方法,但请理解枚举不能扩展任何东西。

于 2013-07-23T20:55:32.043 回答
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 执行所有工作。

您当然可以使用这种技术将大量代码移出父类,但遗憾的是不是全部。

于 2013-08-06T13:39:49.923 回答