如何使用附加接口扩展枚举



我有一个来自另一个库的现有枚举,我无法更改,如下所示:

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());

最新更新