enum
可以实现接口。某些值是否可以实现接口?我正在考虑的用例是标记接口,如下所示:
interface Foo {}
interface Bar {}
enum Widgets {
FOO implements Foo,
BAR_1 implements Bar,
BAR_2 implements Bar
}
这不能在Java 1.8下编译。我知道在内部,为FOO和BAR_1创建了单独的类,所以看起来这是可能的,但我很容易看到标准不支持它。
类似的东西应该有效
interface Widgets;
enum Foo implements Widgets { FOO };
enum Bar implements Widgets { BAR_1, BAR_2 };
这样做的缺点是我不能只做Widgets.values()
并获取所有小部件。
答案 0 :(得分:4)
枚举常量的可选类主体隐式定义了一个 匿名类声明(第15.9.5节),立即扩展 封闭枚举类型。阶级机构由通常的规则管理 匿名课程;特别是它不能包含任何构造函数。 可以在外部调用在这些类主体中声明的实例方法 只有当它们覆盖可访问的方法时才包含枚举类型 封闭的枚举类型(§8.4.8)。
匿名类只能扩展(或实现)新实例创建表达式中指定的类型,在这种情况下为enum
类型。因此,您无法另外实现接口。
以下
enum Foo {
CONSTANT
}
被编译为类似于
的东西class Foo extends Enum<Foo> {
private Foo() {/* calling Enum superconstructor */}
public static final Foo CONSTANT = new Foo();
}
如果你想让常量有一个体(覆盖或声明一些方法)
enum Foo {
CONSTANT {
public String toString() {
return name().toUpperCase();
}
}
}
变得类似
class Foo extends Enum<Foo> {
private Foo() {/* calling Enum superconstructor */}
public static final Foo CONSTANT = new Foo() { // no way to express an additional interface
public String toString() {
return name().toUpperCase();
}
};
}
答案 1 :(得分:2)
枚举值不是类而是实例,因此它们无法实现接口。
但是,如果你想要的只是一种“标记”你的价值观的方法,你可以使用一个字段:
enum Widgets {
FOO(true, false),
BAR_1(false, true),
BAR_2(false, true),
BOTH(true, true);
private final boolean isFoo;
private final boolean isBar;
Widgets(boolean isFoo, boolean isBar) {
this.isFoo = isFoo;
this.isBar = isBar;
}
public boolean foo() {
return isFoo;
}
public boolean bar() {
return isBar;
}
}
在该示例中,您将能够使用Widgets.values()
枚举您的值,并了解每个值是否标记为“foo”,“bar”或两者。
“标记”您的值的另一种方法可以是:
enum Tag {
FOO,
BAR;
}
enum Widgets {
FOO(Tag.FOO),
BAR_1(Tag.BAR),
BAR_2(Tag.BAR),
BOTH(Tag.FOO, Tag.BAR);
private Tag[] tags;
Widgets(Tag... tags) {
this.tags = tags;
}
public Tag[] getTags() {
return tags;
}
}