将此作为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。
答案 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上完成所有工作。
你当然可以使用这种技术将很多代码移出父类,但遗憾的是并非全部。