Intersection-Typen ermöglichen es Ihnen, Sortierungen mit einer Vererbungshierarchie durchzuführen. Sie können die Implementierung nicht erben, aber Sie können sie an eine Hilfsklasse delegieren.Coding Tip - Kreuzungstypen und Java-Enums
enum Foo1 implements Bar {}
enum Foo2 implements Bar {}
class HelperClass {
static <T extends Enum<T> & Bar> void fooBar(T the enum) {}
}
Dies ist nützlich, wenn Sie eine Reihe verschiedener Enums haben, die eine Art Muster implementieren. Zum Beispiel eine Anzahl von Paaren von Enums, die eine Eltern-Kind-Beziehung haben.
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;}
Sie können generische Methoden schreiben, die „Ok, da ein ENUM-Wert das ist ein Elternteil von einigen anderen ENUM-Werte sagen, wie viel Prozent aller möglichen Kind Aufzählungen des Kindes Art dieses bestimmten Stamm Wert als ihre Eltern haben ? ", und haben es alle typsicher und ohne Casting getan. (zB: "Sea" ist 33% aller möglichen Fahrzeuge und "Green" 20% aller möglichen Pastels).
Der Code sieht so aus. Beachten Sie insbesondere, dass die "Blatt" -Klassen selbst recht ordentlich sind - aber die generischen Klassen haben schrecklich hässliche Deklarationen. Das ist in Ordnung: Sie schreiben sie nur einmal. Sobald die generischen Klassen vorhanden sind, ist es einfach, sie zu verwenden.
Die Hilfsklasse unten hat nur einige statische Methoden. Andere Wege gehen zu
- umfassen eine Instanz an, die eine Singleton zurückgibt, aber getippt nach dem Eltern/Kind
- eine Instanz für jeden paren/Kind zurückkehrt, getippt angemessen, und darunter eine in jeder Elternteil enum
Mit dieser zweiten Option, die „Kinder“ Objekt würde innerhalb der Helfer tatsächlich sein, so die Menge an Code in den Aufzählungen benötigt reduzieren. Sie würden alle einen Helfer instantiieren und alles Schwierige delegieren.
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;
}
}
Das ist nicht wirklich eine Frage, aber es kann in eine Frage wert Phrasierung Wieder sein, die Sie selbst beantworten, damit wir sie abstimmen werden. –
Das ist keine Frage, aber ich denke, es gibt einen Platz für etwas auf SO. Ich weiß, dass Jeff die Idee nicht mag, also könntest du geflammt werden. –
Ich muss den vorherigen Kommentaren zustimmen, es wäre viel besser, dies als Frage aufzuschreiben (denken Sie daran, dass Sie Ihre eigenen Fragen beantworten können). –