2012-03-08 22 views
32

मेरे पास एक बहुत ही सरल सवाल है:जावा अंतिम सार श्रेणी

मैं जावा क्लास रखना चाहता हूं, जो एक सार्वजनिक स्थैतिक विधि प्रदान करता है, जो कुछ करता है। यह केवल encapsulating उद्देश्यों के लिए है (सब कुछ एक अलग वर्ग के भीतर महत्वपूर्ण है) ...

इस वर्ग को न तो तत्काल किया जाना चाहिए, न ही विस्तारित किया जाना चाहिए। इससे मुझे लिखा गया:

final abstract class MyClass { 
    static void myMethod() { 
     ... 
    } 
    ... // More private methods and fields... 
} 

(हालांकि मुझे पता था, यह वर्जित है)।

मुझे यह भी पता है कि मैं इस वर्ग को पूरी तरह से अंतिम बना सकता हूं और इसे निजी बनाने के दौरान मानक कन्स्ट्रक्टर को ओवरराइड कर सकता हूं।

लेकिन यह अधिक एक "वर्कअराउंड" की तरह मुझे लगता है और अधिक होने की संभावना अंतिम सार वर्ग द्वारा किया जाना चाहिए ...

और मैं समाधानों से नफरत है। तो सिर्फ अपनी रुचि के लिए: क्या कोई और बेहतर तरीका है?

+0

सिंगलटन पैटर्न? –

+5

आप कक्षा सार क्यों बनाना चाहते हैं? सार वर्ग का अर्थ है कि कुछ घोषित लेकिन अनुपूरक विधियां हैं, जो ** ** कक्षाओं का विस्तार ** _must_ कार्यान्वित करती हैं। –

+5

@ एलेक्स जी: यह सच नहीं है ... सार वर्ग का अर्थ है: आप इसे तुरंत चालू नहीं कर सकते हैं। आपको उस वर्ग के भीतर अमूर्त तरीकों को परिभाषित करने में असफलता नहीं है ... बेशक आप सही हैं। आम तौर पर आप जैसे अमूर्त वर्गों का उपयोग करेंगे। लेकिन यह सिर्फ एक "बिंदु-दृश्य" चीज है। मैं हमेशा अमूर्त तरीकों को परिभाषित किए बिना अपने बड़े फैक्ट्री वर्गों का सार बना देता हूं। – Sauer

उत्तर

42

संदर्भ: प्रभावी जावा 2 संस्करण मद 4

public final class MyClass { //final not required but clearly states intention 
    //private default constructor ==> can't be instantiated 
    //side effect: class is final because it can't be subclassed: 
    //super() can't be called from subclasses 
    private MyClass() { 
     throw new AssertionError() 
    } 

    //... 
    public static void doSomething() {} 
} 
+39

@LuiggiMendoza यह _not_ एक सिंगलटन पैटर्न है। यहां बिल्कुल कोई उदाहरण नहीं है। –

+0

हां, लेकिन इसके लिए सिंगलटन पैटर्न एक उपयुक्त समाधान हो सकता है। –

+0

मैं इसे 'अंतिम' बनाउंगा, ऐसा नहीं कि जेडीके 6/जे 2 एसई 5.0 के बाद से कोई फर्क पड़ता है। –

4

नहीं "एक निजी निर्माता के साथ noninstantiability लागू करें", सार कक्षाएं बढ़ाया जा के लिए होती हैं। निजी कन्स्ट्रक्टर का प्रयोग करें, यह एक कामकाज नहीं है - यह करने का तरीका है!

6

नहीं, आपको क्या करना चाहिए एक निजी खाली कन्स्ट्रक्टर बनाना जो उसके शरीर में अपवाद फेंकता है। जावा एक ऑब्जेक्ट-ओरिएंटेड भाषा है और एक वर्ग जिसे तत्काल नहीं किया जाना चाहिए, वह स्वयं ही एक काम है! :)

final class MyLib{ 
    private MyLib(){ 
     throw new IllegalStateException("Do not instantiate this class."); 
    } 

    // static methods go here 

} 
+0

@assylias: * "कक्षा अंतिम होगी क्योंकि इसे उपclassed नहीं किया जा सकता" *। यह "अंतिम" की आपकी परिभाषा पर निर्भर करता है। ऐसा नहीं है कि निजी कन्स्ट्रक्टर की वजह से वर्ग को अंतिम रूप से * अंतिम * बनाया गया था (वैसे, कहें, इंटरफ़ेस विधियों को सार्वजनिक रूप से घोषित नहीं किया जाता है)। उदाहरण के लिए * सार्वजनिक फाइनल * या बस * सार्वजनिक * ** ** ** दो अलग-अलग * .class * फ़ाइलों को उत्पन्न किया जाएगा: * अंतिम * * .class * के साथ इसके एक्सेस झंडे 0x31 (सार्वजनिक फ़ाइनल) पर सेट हैं जबकि केवल * सार्वजनिक * के साथ इसके एक्सेस झंडे 0x21 हैं। आप इसे विस्तारित नहीं कर सकते हैं लेकिन यह अभी भी * अंतिम * नहीं है ... – TacticalCoder

+0

@ArtB लेकिन आप सहमत होंगे कि निम्नलिखित भी बकवास है ?: विकल्प "ऑब्जेक्ट-क्लास" लिखने और एक बार कन्स्ट्रक्टर को कॉल करने के लिए होगा, जो क्या सभी काम करता है ... इस वस्तु का उपयोग करने में कोई और बात नहीं है। इसमें कोई विनाशक नहीं है, कोई गेटर नहीं, कोई सेटटर नहीं है ... वस्तु इस मामले में व्यर्थ है, क्योंकि सभी वस्तुएं बिल्कुल वही होंगी। यह वास्तव में, किस स्थिर तरीके के लिए हैं। और अलग-अलग कक्षाओं में सामान को समाहित करने के लिए यह अच्छा अभ्यास है (यानी "फाइलें")। बेशक मैं अपने कॉलिंग क्लास में सब कुछ कर सकता हूं। लेकिन यह बहुत अधिक होगा ... – Sauer

+0

@ सॉयर विनिर्देशों को जानने के बिना एक विकल्प प्रदान करना मुश्किल है, लेकिन ऑब्जेक्ट उन्मुख डिजाइन सिद्धांतों के साथ बेहतर होने पर काम करने के बाद मुझे लगता है कि बहुत ही कम तरीके से स्थिर तरीकों की आवश्यकता है। केवल एकमात्र मामले जो मैं वास्तव में औचित्य साबित कर सकता हूं वे वे हैं जहां आप कक्षाओं में मौजूद होना चाहिए या नल मुद्दों से निपटने के लिए हैं। – ArtB

45

आप कोई उदाहरण के साथ एक enum का उपयोग करने से बहुत सरल नहीं मिल सकता है।

public enum MyLib {; 

    public static void myHelperMethod() { } 
} 

यह कक्षा अंतिम है, स्पष्ट रूप से कोई उदाहरण और निजी निर्माता नहीं है।

यह रनटाइम त्रुटि के बजाए संकलक द्वारा पता चला है। (अपवाद फेंकने के विपरीत)

+8

यह एकदम सही समाधान है। मुझे समझ में नहीं आता कि लोग इसे वोट क्यों नहीं देते हैं। – AlexR

+2

@AlexR मैं सिंगलटन के लिए भी इसी कारण से enum का उपयोग करता हूं। आप स्पष्ट रूप से कह रहे हैं कि कितने उदाहरण हो सकते हैं। 'enum' सिंगलेट्स के मामले में इंटरफेस का विस्तार कर सकते हैं। –

+4

पीटर लॉरी 1 - 0 जोशुआ ब्लोच ;-) (मजेदार है कि जेबी का उल्लेख नहीं है कि जब वह सिंगल के लिए इतनी दृढ़ता से एनम का उपयोग करने की वकालत करता है) – assylias

1

एशिलियास (सभी जावा संस्करण) और पीटर लॉरे (> = जावा 5) के सुझाव इस मामले में जाने का मानक तरीका हैं।

हालांकि मैं आपका ध्यान रखना चाहता हूं कि स्थैतिक उपयोगिता वर्ग के विस्तार को रोकने का एक बहुत ही अंतिम निर्णय है जो आपको बाद में परेशान करने के लिए आ सकता है, जब आपको लगता है कि आपके पास एक अलग परियोजना में संबंधित कार्यक्षमता है और आप वास्तव में इसे विस्तारित करना चाहते हैं।

public abstract MyClass { 

    protected MyClass() { 
    } 

    abstract void noInstancesPlease(); 

    void myMethod() { 
     ... 
    } 
    ... // More private methods and fields... 

} 

यह हो जाता है के खिलाफ अभ्यास की स्थापना के बाद से यह वर्ग के विस्तार की अनुमति देता है जब जरूरत, यह अभी भी आकस्मिक इन्स्टेन्शियशन (आप भी बिना एक गुमनाम उपवर्ग उदाहरण नहीं बना सकते रोकता है:

मैं निम्नलिखित सुझाव एक बहुत स्पष्ट संकलक त्रुटि हो रही है)।

यह हमेशा pisses मुझे लगता है कि जेडीके की उपयोगिता कक्षाएं (उदाहरण के लिए java.util.Arrays) वास्तव में अंतिम बना दी गई थीं। यदि आप चाहते हैं कि आपके पास एरेज़ क्लास है, तो विधियों के साथ तुलना करने के लिए कहें, आप नहीं कर सकते हैं, आपको एक अलग वर्ग बनाना है।यह कार्यक्षमता वितरित करेगा कि (आईएमओ) एक साथ संबंधित है और एक कक्षा के माध्यम से उपलब्ध होना चाहिए। इससे आपको या तो जंगली रूप से वितरित उपयोगिता विधियों के साथ छोड़ दिया जाता है, या आपको अपनी खुद की कक्षा में प्रत्येक विधि को डुप्लिकेट करना होगा।

मैं ऐसी उपयोगिता कक्षाओं को अंतिम बनाने की सलाह नहीं देता हूं। फायदे मेरी राय में नुकसान को कम नहीं करते हैं।

+0

मुझे आपकी बात मिली और उसने मुझे अपने डिजाइन के बारे में सोचा। लेकिन मेरे मामले में, मैं वास्तव में वास्तव में किसी को अपनी कक्षा का विस्तार नहीं करना चाहता हूं। यही कारण है कि यह डिफ़ॉल्ट दृश्यता "अंतिम श्रेणी MyClass" (सार्वजनिक के बिना) है। यह केवल मेरे पैकेज के भीतर मान्य है और कोई भी उस पैकेज के बाहर इसका उपयोग करने में सक्षम नहीं होना चाहिए। और कोई भी पैकेज के अंदर इसे विस्तारित करने में सक्षम नहीं होना चाहिए। लेकिन वैसे भी: उस "नोइन्सेंस कृपया" अमूर्त विधि के साथ अच्छा विचार ... मैं इसे ध्यान में रखूंगा – Sauer

-2

Check this Reference Site..

संभव नहीं है। वंचित किए बिना एक अमूर्त वर्ग का कोई उपयोग नहीं है और इसलिए परिणामस्वरूप समय त्रुटि संकलित होगी।

धन्यवाद ..

2

वर्ग के निर्माता घोषित private किया जाना है। यह noninstantability सुनिश्चित करता है और subclassing रोकता है।

0

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

-1

यह सादा अंग्रेजी में बहुत ही सरल स्पष्टीकरण है। एक सार वर्ग को तत्काल नहीं किया जा सकता है और केवल बढ़ाया जा सकता है। अंतिम श्रेणी को बढ़ाया नहीं जा सकता.अब यदि आप अंतिम कक्षा के रूप में एक अमूर्त वर्ग बनाते हैं, तो आप कैसे सोचते हैं कि आप ' कभी भी उस वर्ग का उपयोग करने वाला है, और वास्तव में, क्या वास्तव में इस तरह के जाल में खुद को रखने के लिए तर्क है?

+1

आप सही हैं। लेकिन, जैसा कि मैंने कहा था: मैं इस वर्ग का उपयोग स्थिर तरीकों के टूलबॉक्स के लिए करना चाहता हूं। इसलिए मैं न तो इंस्टाल करना चाहता हूं, न ही इसे विस्तारित करना चाहता हूं। – Sauer

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