我有一个来自另一个库的现有枚举,我无法更改,如下所示:
enum PersonTypes {
ADT("Adult"), CHD("Child"), INF("Infant");
private String value;
PersonTypes(String value) { this.value = value; }
}
我想用一个接口来增强枚举,以便提供一些功能。当然,下面的代码是无效的,但它展示了我试图实现的目标:
enum PrintablePersonTypes implements Printable {
PersonTypes.ADT, PersonTypes.CHD, PersonTypes.INF;
@Override
public void printme() {
sysout("I'm a " + super.value);
}
}
类Lateron:
List<PrintablePersonTypes> list;
list.stream.forEach(p -> o.printme());
这有可能吗?
我认为枚举不可能做到这一点。由于枚举是";隐含最终";,以及";枚举常量定义枚举类型"的实例;JLS 8.9,您既不能使用继承,也不能定义不同类型的枚举常量。
我能想到的最接近的东西
enum PrintablePersonTypes implements Printable {
ADT(PersonTypes.ADT),
CHD(PersonTypes.CHD),
INF(PersonTypes.INF);
private PersonTypes pt;
private PrintablePersonTypes(PersonTypes pt) {
this.pt = pt;
}
@Override
public void printme() {
sysout("I'm a " + pt.value);
}
}
即通过成员显式地创建映射。
我想问您是否真的需要这个方法成为枚举本身(或任何枚举(的成员。
枚举是最终的,因此不存在子类化的可能性;因此,如果方法的实现是枚举的实例成员,那么它将有效地静态绑定到该实现。
相反,在其他类中定义一个静态方法:
public static void printme(PersonTypes pt) {
sysout("I'm a " + pt.value);
}
然后在你的流中调用这个:
list.stream.forEach(SomeOtherClass::printme);
java中的枚举是最终的,不是为子类化而设计的。如果必须使用自定义枚举,而不是例如Map<String,whatever>
,则可以将枚举定义为包装
enum PrintablePersonTypes implements Printable {
ADT(PersonTypes.ADT),
CHD(PersonTypes.CHD),
INF(PersonTypes.INF);
private PrintablePersonTypes(PersonTypes wrapped) {
this.wrapped = wrapped;
}
PersonTypes wrapped;
@Override
public void printme() {
sysout("I'm a " + wrapped.name());
}
}
然后,您可能需要解决一些与原始枚举的同步问题。删除是免费的,并且在编译器级别(如果原始枚举常量被删除,您的枚举就会中断(。添加并不那么容易——您可以通过枚举或检查名称映射来使用switch
,但这是运行时的问题,而不是compiletime。
之类的东西怎么样
public class PrintablePersonTypes implements Printable {
private PersonTypes me;
private List<PersonTypes> allValues = PersonTypes.values();
public getAllValues() {
return allValues;
}
public PrintablePersonTypes(final PersonTypes personTypes) {
this.me = personTypes;
}
@Override
public void printme() {
sysout("I'm a " + me);
}
}
稍后:
List<PrintablePersonTypes> list = new ArrayList<>();
list.add(new PrintablePersonTypes(PersonTypes.INF));
list.stream.forEach(p -> o.printme());