交集类型允许您(有点排序)执行具有继承层次结构的枚举。您不能继承实现,但可以将其委托给辅助类。
enum Foo1 implements Bar {}
enum Foo2 implements Bar {}
class HelperClass {
static <T extends Enum<T> & Bar> void fooBar(T the enum) {}
}
当您有许多实现某种模式的不同枚举时,这很有用。例如,有许多具有父子关系的枚举对。
enum PrimaryColor {Red, Green, Blue;}
enum PastelColor {Pink, HotPink, Rockmelon, SkyBlue, BabyBlue;}
enum TransportMedium {Land, Sea, Air;}
enum Vehicle {Car, Truck, BigBoat, LittleBoat, JetFighter, HotAirBaloon;}
您可以编写通用方法,说“好的,给定一个枚举值,该值是某些其他枚举值的父级,子类型的所有可能子枚举中有多少百分比将此特定父值作为其父级?”,以及拥有所有类型安全和没有铸造完成。 (例如:“Sea”占所有可能车辆的33%,而“Green”占所有可能车辆的20%)。
代码看起来像这样。特别要注意的是“叶子”类本身非常简洁 - 但泛型类的声明非常难看。没关系:你只写一次。一旦通用类存在,那么使用它们很容易。
下面的助手类只有一些静态方法。其他方法包括
使用第二个选项,“children”对象实际上将位于帮助器内,因此减少了枚举中所需的代码量。他们都会实例化一个帮助者,并将任何困难的事情委托给他们。
import java.util.EnumSet;
import javax.swing.JComponent;
public class zz extends JComponent {
public static void main(String[] args) {
System.out.println(PrimaryColor.Green + " " + ParentUtil.pctOf(PrimaryColor.Green) + "%");
System.out.println(TransportMedium.Air + " " + ParentUtil.pctOf(TransportMedium.Air) + "%");
}
}
interface Parent<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
Class<C> getChildClass();
EnumSet<C> getChildren();
}
interface Child<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
Class<P> getParentClass();
P getParent();
}
enum PrimaryColor implements Parent<PrimaryColor, PastelColor> {
Red, Green, Blue;
private EnumSet<PastelColor> children;
public Class<PastelColor> getChildClass() {
return PastelColor.class;
}
public EnumSet<PastelColor> getChildren() {
if(children == null) children=ParentUtil.loadChildrenOf(this);
return children;
}
}
enum PastelColor implements Child<PrimaryColor, PastelColor> {
Pink(PrimaryColor.Red), HotPink(PrimaryColor.Red), //
Rockmelon(PrimaryColor.Green), //
SkyBlue(PrimaryColor.Blue), BabyBlue(PrimaryColor.Blue);
final PrimaryColor parent;
private PastelColor(PrimaryColor parent) {
this.parent = parent;
}
public Class<PrimaryColor> getParentClass() {
return PrimaryColor.class;
}
public PrimaryColor getParent() {
return parent;
}
}
enum TransportMedium implements Parent<TransportMedium, Vehicle> {
Land, Sea, Air;
private EnumSet<Vehicle> children;
public Class<Vehicle> getChildClass() {
return Vehicle.class;
}
public EnumSet<Vehicle> getChildren() {
if(children == null) children=ParentUtil.loadChildrenOf(this);
return children;
}
}
enum Vehicle implements Child<TransportMedium, Vehicle> {
Car(TransportMedium.Land), Truck(TransportMedium.Land), //
BigBoat(TransportMedium.Sea), LittleBoat(TransportMedium.Sea), //
JetFighter(TransportMedium.Air), HotAirBaloon(TransportMedium.Air);
private final TransportMedium parent;
private Vehicle(TransportMedium parent) {
this.parent = parent;
}
public Class<TransportMedium> getParentClass() {
return TransportMedium.class;
}
public TransportMedium getParent() {
return parent;
}
}
class ParentUtil {
private ParentUtil(){}
static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
float pctOf(P parent) {
return (float) parent.getChildren().size() / //
(float) EnumSet.allOf(parent.getChildClass()).size() //
* 100f;
}
public static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
EnumSet<C> loadChildrenOf(P p) {
EnumSet<C> cc = EnumSet.noneOf(p.getChildClass());
for(C c: EnumSet.allOf(p.getChildClass())) {
if(c.getParent() == p) {
cc.add(c);
}
}
return cc;
}
}
答案 0 :(得分:1)
您可以使用Commons Enum实现:
http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/enums/Enum.html
允许您创建可以进行子类化的Enum。
答案 1 :(得分:0)
这更简单,它能做你想做的吗?
import java.util.*;
interface Tree{
Tree parent();
Set<Tree> children();
}
enum PrimaryColor implements Tree {
Red,Green,Blue;
@Override public Tree parent() {
return null;
}
@Override public Set<Tree> children() {
return Collections.unmodifiableSet(children);
}
final Set<Tree> children=new LinkedHashSet<Tree>();
}
enum PastelColor implements Tree {
Pink(PrimaryColor.Red),HotPink(PrimaryColor.Red),Rockmelon(PrimaryColor.Green),SkyBlue(PrimaryColor.Blue),BabyBlue(PrimaryColor.Blue);
PastelColor(final PrimaryColor primaryColor) {
this.primaryColor=primaryColor;
if (primaryColor!=null) primaryColor.children.add(this);
}
@Override public Tree parent() {
return primaryColor;
}
@Override public Set<Tree> children() {
return Collections.emptySet();
}
double percent() {
return primaryColor.children().size()*100./EnumSet.allOf(super.getClass()).size();
}
private final PrimaryColor primaryColor;
}
public class Main{
static double percent(final Tree tree) {
final Tree parent=tree.parent();
if (tree instanceof Enum) { return parent.children().size()*100./((Enum)tree).getClass().getEnumConstants().length; }
else throw new RuntimeException("strange tree!");
}
public static void main(String[] args) {
System.out.println("one way");
for(PastelColor pastelColor:PastelColor.values())
System.out.println(pastelColor+" "+pastelColor.percent());
System.out.println("another way");
for(PastelColor pastelColor:PastelColor.values())
System.out.println(pastelColor+" "+percent(pastelColor));
}
}