2015-01-12 3 views
21

यहां लघु संस्करण है। सबसे पहले और सबसे महत्वपूर्ण: मैं चाहता हूं कि मेरी कक्षा अपरिवर्तनीय हो। मुझे पता है कि एक वर्ग सार और अंतिम दोनों नहीं हो सकता है। मैं जो पूछ रहा हूं वह है: क्या केवल का कोई तरीका है आंतरिक कक्षाओं को बाहरी, अमूर्त वर्ग को विस्तार और कार्यान्वित करने की अनुमति देता है? यह मेरे अपरिवर्तनीय लक्ष्यों को प्राप्त करने का सबसे अच्छा तरीका नहीं हो सकता है, इसलिए यदि किसी के पास बेहतर डिज़ाइन है, तो मुझे यह सुनना अच्छा लगेगा।कोई एक अमूर्त, अपरिवर्तनीय वर्ग कैसे बना सकता है?

मैं वेक्टर परिचालनों के लिए एक कक्षा लिख ​​रहा हूं - भौतिकी और इंजीनियरिंग में, प्रोग्रामिंग भावना नहीं। (मैं भी पता है कि सामान के इस प्रकार के लिए JScience has a package। मैं अपने खुद के बारे में है, और यह सरल बनाए रखना चाहते हूँ।)

मैं जावा के ज्यामिति पैकेज में इस्तेमाल किया पद्धति की तरह, जिसमें, कहते हैं, एक Line2D बनाया जा सकता है दो परिशुद्धता स्तरों में से एक का उपयोग करना: फ्लोट या डबल।

public abstract class Line2D { 
    public static class Float extends Line2D { /* Implementation */ } 
    public static class Double extends Line2D { /* Implementation */ } 
} 

यह मैं वास्तव में मेरी कक्षा में शामिल और उनका विस्तार करना चाहते हैं एक विशेषता है, इसलिए मैं निम्नलिखित बनाया:

public abstract class Vector2D { 

    public final static class Integer extends Vector2D { 

     // Component length projected along x/y axis, respectively 
     final private int i, j; 

     public Integer(int i, int j) { 
      this.i = i; 
      this.j = j; 
     } 

     public Object doStuff() { /* vector operations */ } 
    } 

    public final static class Float extends Vector2D { 
     // Identical to Vector2D.Integer, except with floats 
    } 

    public final static class Double extends Vector2D { /* Same Idea */ } 

    // Outer class methods and whatnot 
} 

जाहिर है, Vector2D.Integer, Vector2D.Float, और Vector2D.Double सभी अंतिम कर रहे हैं। क्या इन आंतरिक कक्षाओं को छोड़कर Vector2D सब कुछ करने के लिए अंतिम तरीका है?

+0

वैसे - क्या आप इसके लिए जेनिक्स का उपयोग नहीं कर सकते? अधिकांश परिचालनों के साथ उनके साथ काम करना चाहिए और यह वेक्टर के बजाय वेक्टर लिखने के लिए अधिक मूर्खतापूर्ण है। इंटेगर ... फिर आपको चारों ओर कास्टिंग करने की आवश्यकता नहीं होगी ... – Falco

+1

@ फाल्को प्रदर्शन आवश्यकताओं के आधार पर, मुक्केबाजी/अनबॉक्सिंग रूपांतरण (दुर्भाग्य से अभी भी) निषिद्ध रूप से महंगा हो सकता है (आखिरी लेकिन कम से कम लाखों 'डबल' उदाहरणों द्वारा निहित संभावित कचरे के कारण नहीं। इसके विशेषज्ञों के लिए एक कारण है, उदाहरण के लिए, जावा 8 में 'स्ट्रीम' को 'डबलस्ट्रीम' के रूप में 'स्ट्रीम करें ...) – Marco13

उत्तर

25

है वहाँ एक रास्ता केवल इनर क्लासों का विस्तार करने और बाहरी, सार वर्ग को लागू करने के लिए अनुमति देने के लिए:

यहाँ इन वर्गों के लिए प्रासंगिक स्रोत कोड है?

हां, बाहरी वर्ग निजी के निर्माता बनाओ।

उदाहरण:

abstract class MyAbstractClass { 
    int i; // some property 
    private MyAbstractClass(int i) { 
     this.i = i; 
    } 

    public static class InnerConcrete extends MyAbstractClass { 
     int j; // some other property 
     public InnerConcrete(int i, int j) { 
      super(i); 
      this.j = j; 
     } 
    } 
} 

मुझे नहीं लगता कि मैं कभी भी इस दृष्टिकोण का सामना करना पड़ा। एक कारखाना पैटर्न अधिक लचीला हो सकता है और आपको अन्यथा संभावित रूप से बड़ी कक्षा को कई फाइलों में विभाजित करने की अनुमति देता है। अमूर्त वर्ग का पैकेज पहुंच स्तर शायद भी पर्याप्त हो सकता है।

+0

मैं इस दृष्टिकोण के बारे में भूल गया। लेकिन क्या यह एक अजीब डिजाइन का कारण नहीं है? –

+0

@ लुइगी मैन्डोज़ा, आप अजीब से क्या मतलब है? – aioobe

+0

मेरा मतलब है, इस उद्देश्य को प्राप्त करने के लिए शीर्ष वर्गों के बजाय आंतरिक 'स्थिर' कक्षाओं का उपयोग क्यों करें? –

10

क्या आंतरिक कक्षाओं को बाहरी, अमूर्त वर्ग को विस्तार और कार्यान्वित करने की अनुमति देने का कोई तरीका है?

मैं एक और विकल्प चुनता हूं: अपने अमूर्त वर्गों को गैर-सार्वजनिक बनाएं और केवल final कार्यान्वयन कक्षाएं सार्वजनिक करें। AbstractStringBuilder का यह मामला है, जो java.lang पैकेज से संबंधित है, abstract और गैर -public है, और इसे StringBuilder और StringBuffer कक्षाओं द्वारा लागू किया गया है, जो public final हैं।

abstract class AbstractStringBuilder implements Appendable, CharSequence { 
    //implementation details... 
} 

public final class StringBuilder 
    extends AbstractStringBuilder 
    implements java.io.Serializable, CharSequence { 
    //implementation details... 
} 

public final class StringBuffer 
    extends AbstractStringBuilder 
    implements java.io.Serializable, CharSequence { 
    //implementation details... 
} 
+0

यह एक अच्छा विकल्प हो सकता है अगर मैं कुछ अलग कर रहा था। हालांकि, मैं केवल आंतरिक कक्षाओं के साथ चला गया क्योंकि वे सभी प्रभावी ढंग से वही हैं और वही चीजें करते हैं, केवल परिशुद्धता के विभिन्न स्तरों के साथ। उन्हें अलग-अलग वर्गों में विभाजित करने से इस मामले में इसकी कीमत के मुकाबले अधिक जटिलता बढ़ जाएगी। इसके अलावा, यह एक अच्छा समाधान है। – drmuelr

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