2009-02-22 13 views
8

छेड़छाड़ के प्रकार आपको विरासत पदानुक्रम वाले एंट्स (थोड़े सॉर्टा) की अनुमति देते हैं। आप कार्यान्वयन का वारिस नहीं कर सकते हैं, लेकिन आप इसे एक सहायक वर्ग में भेज सकते हैं।कोडिंग टिप - चौराहे के प्रकार और जावा एनम्स

enum Foo1 implements Bar {} 
enum Foo2 implements Bar {} 

class HelperClass { 
    static <T extends Enum<T> & Bar> void fooBar(T the enum) {} 
} 

यह तब उपयोगी होता है जब आपके पास कई प्रकार के पैटर्न लागू होते हैं जो विभिन्न प्रकार के पैटर्न को लागू करते हैं। उदाहरण के लिए, उन enums के जोड़े जो माता-पिता के बच्चे के रिश्ते हैं।

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;} 

आप सामान्य तरीकों कि कहते हैं कि "ठीक है, एक enum मान दिया कुछ अन्य enum मूल्यों की एक माता पिता, बच्चे प्रकार के सभी संभव बच्चे enums कि कितने प्रतिशत अपने माता पिता के रूप में इस विशेष माता पिता मूल्य है thats लिख सकते हैं ? ", और यह सभी प्रकार के हैं और कास्टिंग के बिना किया है। (उदाहरण: कि "सागर" सभी संभावित वाहनों का 33% है, और "ग्रीन" सभी संभावित पेस्टल का 20%)।

कोड इस तरह दिखता है। विशेष रूप से ध्यान दें कि "पत्ता" वर्ग स्वयं काफी साफ हैं - लेकिन सामान्य वर्गों में ऐसी घोषणाएं होती हैं जो बहुत बदसूरत हैं। यह ठीक है: आप केवल उन्हें एक बार लिखते हैं। एक बार जेनेरिक कक्षाएं हैं, तो उनका उपयोग करना आसान है।

नीचे सहायक सहायक वर्ग में कुछ स्थिर विधियां हैं। अन्य तरीके

  • शामिल एक उदाहरण है कि एक सिंगलटन रिटर्न प्रदान करने जाना है, लेकिन माता पिता/बच्चे
  • प्रत्येक कोष्ठक/बच्चे के लिए एक उदाहरण लौटने के अनुसार टाइप किया, उचित रूप से टाइप किया है, और में एक सहित हर माता-पिता enum

इस दूसरे विकल्प के साथ, "बच्चों" वस्तु वास्तव में सहायक के अंदर होगा, इसलिए enumerations में आवश्यक कोड की संख्या को कम करने। वे सभी एक सहायक को तत्काल करेंगे, और कुछ भी मुश्किल से प्रतिनिधि करेंगे।

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

यह वास्तव में एक प्रश्न नहीं है, लेकिन यह एक प्रश्न में फिर से वाक्यांश के लायक हो सकता है कि आप स्वयं का जवाब देते हैं ताकि हम इसे वोट दे सकें। –

+0

यह कोई सवाल नहीं है लेकिन मुझे लगता है कि एसओ पर चीज की तरह एक जगह है। मुझे पता है कि जेफ इस विचार को पसंद नहीं करते हैं, हालांकि आप फ्लेम हो सकते हैं। –

+0

मुझे पिछली टिप्पणियों से सहमत होना है, यह एक प्रश्न के रूप में लिखा जाना बेहतर होगा (याद रखें कि आप अपने प्रश्नों का उत्तर दे सकते हैं)। –

उत्तर

1

तुम बस के बजाय कॉमन्स Enum कार्यान्वयन इस्तेमाल कर सकते हैं:

http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/enums/Enum.html

जो आप बनाना Enum के तत्कालीन subclassed जा सकता है कि अनुमति देता है।

+0

वास्तविक enums के लाभ हैं हालांकि, उन पर स्विच करने की क्षमता()। – StaxMan

+0

असली enums भी विशेष रूप से जावा serialization द्वारा संभालती है। – paulmurray

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)); 
    } 
} 
+0

बिंदु को चीजों को एन्म में डालना नहीं है - इसे संकलित समय पर टाइप-सुरक्षित करने के लिए। – paulmurray

संबंधित मुद्दे