在 Java 中使用嵌套枚举类型
我脑子里有一个涉及嵌套枚举的数据结构,这样我就可以做类似以下的事情:
Drink.COFFEE.getGroupName();
Drink.COFFEE.COLUMBIAN.getLabel();
如果有方法声明:那么
someMethod(Drink type)
someOtherMethod(DrinkTypeInterface type)
我可以(适当地)说:
someMethod(Drink.COFFEE)
someOtherMethod(Drink.COFFEE.COLUMBIAN)
这就是我想出的:
public enum Drink {
COFFEE("Coffee");
private String groupName;
private Drink(String groupName) {
this.groupName = groupName;
}
public enum Coffee implements DrinkTypeInterface {
COLUMBIAN("Columbian Blend"),
ETHIOPIAN("Ethiopian Blend");
private String label;
private Coffee(String label) {
this.label = label;
}
public String getLabel() {
return this.label;
}
}
String getGroupName() {
return this.groupName;
}
}
以及接口:
public interface DrinkTypeInterface {
public String getLabel();
}
我我想我只是想弄清楚在 Java 中做这类事情的最佳方法是什么,或者我是否需要编写一堆 if 语句来处理单个 Drink.values()。有什么帮助吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,您提供的示例代码在某种程度上违反了“德米特定律” - 因为 COLUMBIAN 实例字段仅用于检索标签。另外,通过该结构,COLUMBIAN 必须是 COFFEE 枚举的一个实例,但我认为这并不是您真正想要的。
我从你的样本中收集到的是,你想要一个包含实际饮料的“组类型”的枚举,然后每个类型都有特定类型饮料的单独值。你的例子给出了咖啡,但茶也应该同样有效。
问题在于您如何放置枚举。正如我之前所说,您必须使 COLUMBIAN 成为 COFFEE 枚举的实例,但这实际上并不是构建此枚举的最佳方法。
问题是你有饮料,然后是咖啡/茶,然后是它们各自的类型。
但是,如果您想一想,虽然草茶是一种茶,但它也是一种饮料 - 因此它不只是茶的一个实例。
但是,如果您使饮料类型本身成为一个枚举,您就会得到您想要的东西,并且结构会变得更加清晰。并且由于接口和委托的力量,饮料类型和饮料枚举都可以以相同的方式处理,如以下示例程序所示:
该程序的输出如下:
现在,如果由于某种原因您不希望你所有的饮料都在一个枚举中,那么我就不明白你想要什么。在这种情况下,如果您确实具有跨越枚举的功能,请单独进行咖啡和茶(以及其他)枚举,并将接口应用于两个(或多个)枚举。但是,我认为你试图像这样将它们分组。
First off, that sample code you gave violates the "law of demeter" somewhat - as the COLUMBIAN instance field is only used to retrieve the label. Also, with that structure, COLUMBIAN has to be an instance of the COFFEE enum, but I don't think that's what you're really going for here.
What I'm gathering from what your sample is, is that you want to have an enumeration that contains a "group type" of what the actual drink is, and then each one has individual values for the specific type of drink. Your example gives Coffee, but Tea should work just as well.
The problem is how you've placed your enumerations. As I said before, you'd have to make COLUMBIAN an INSTANCE of the COFFEE enumeration, but that's not really the best way to structure this.
The problem is that you've got Drink, then Coffee/Tea, and then their individual types.
But, if you think about it, although HerbalTea IS A Tea, it is also a DRINK - so it doesn't belong as simply an instance of a TEA.
But, if you make the drink type an enum in and of itself, you get what you wanted, and the structure becomes clearer. And due to interfaces and the power of delegation, both the drink type and the drink enum can be processed in the same manner, as with the following example program:
The output of this program is as follows:
Now then, if for some reason you didn't want all your drinks in a single enum, then I didn't understand what you were going for. In that case, if you do have functionality that spans the enums, make separate Coffee and Tea (and whatever) enumerations and apply the interface on both (or more) enumerations. But, I think you were trying to group them like this.
考虑使用
EnumSet
按照建议饮料 href="https://stackoverflow.com/questions/6559163/stopping-repetition-in-java-enums/6559541#6559541">此处。附录:作为一个具体示例,下面的代码产生所示的输出。
代码:
Consider using
EnumSet
to collect different types ofDrink
, as suggested here.Addendum: As a concrete example, the code below produces the output shown.
Code:
我最近很好奇这是否可以做得令人满意。这是我最终得到的解决方案,我认为其 API 也更接近提问者最初想要的枚举树结构:
I was recently curious myself if this could be done somewhat satisfactorily. This is the solution I ended up with, whose API I think also closer matches the tree structure of enums that the asker originally wanted:
你可以这样做:
you can do something like: