2011-01-25 14 views
32

यह सीधे एक abstract वर्ग के निर्माता को फोन करके एक वस्तु बनाने के लिए संभव नहीं है की एक सार्वजनिक निर्माता के लिए अच्छा कारण हैं। abstract वर्ग के निर्माता को केवल व्युत्पन्न कक्षा से ही बुलाया जा सकता है। इसलिए यह मेरे लिए लगता है कि एक अमूर्त वर्ग के निर्माताओं या तो protected या पैकेज-निजी (पैकेज में व्युत्पन्न वर्ग के लिए एक निर्माता के उपयोग को प्रतिबंधित की असामान्य मामलों के लिए बाद)। फिर भी जावा abstract वर्ग के निर्माता को public होने की अनुमति देता है।वहाँ एक अमूर्त वर्ग

वहाँ किसी भी जिन परिस्थितियों में यह उपयोगी एक abstract वर्ग के निर्माता की घोषणा करने के public, बजाय protected या पैकेज-निजी होने के लिए कर रहे हैं?

यह काफी सवाल का "Abstract class constructor access modifier" एक नकली नहीं है: स्पष्ट रूप से आप public होने के लिए एक निर्माता घोषणा कर सकते हैं; मैं जानना चाहता हूं कि ऐसा करने के लिए कोई भी अच्छा है। ऐसा लगता है कि ऐसा नहीं है। मैं देखता हूं कि C# has a similar peculiarity

+0

कन्स्ट्रक्टर के पास ऑब्जेक्ट के "निर्माण" के साथ कुछ लेना देना नहीं है। यह केवल एक विधि है जिसे किसी वस्तु को "बनाने" के दौरान बुलाया जाता है। इस प्रकार, सार वर्ग में सार्वजनिक रचनाकार हो सकते हैं जिन्हें सार वर्ग (सबक्लास के माध्यम से) और उस कन्स्ट्रक्टर-विधि में उदाहरण बनाते समय कहा जाएगा, आप सदस्य चर को प्रारंभ करने के लिए कोड लिखेंगे। http://stackoverflow.com/questions/260666/can-an-abstract-class-have-a-constructor?lq=1 –

+1

कन्स्ट्रक्टर भी 'निजी' हो सकते हैं, जिसका उपयोग कन्स्ट्रक्टर चेनिंग में किया जा सकता है। –

उत्तर

16

जवाब जावा के लिए एक ही है:

वहाँ एक अमूर्त वर्ग के लिए एक सार्वजनिक निर्माता के लिए कोई कारण नहीं है। मुझे लगता है कि संकलक शिकायत नहीं करता है कि यह कारण इतना आसान है कि उन्होंने समय को कवर करने में समय नहीं लगाया क्योंकि यह वास्तव में कोई फर्क नहीं पड़ता कि यह सार्वजनिक है या संरक्षित है। (source)

आप सीधे उप-वर्ग के अलावा किसी अन्य चीज़ से किसी सारणी वर्ग के निर्माता को कॉल नहीं कर सकते हैं।

तो सार वर्गों के निर्माताओं की पहुँच संशोधक के लिए एक विशेष नियम जोड़ने कुछ भाषा के लिए उपयोगी जोड़ नहीं होगा।


एक बात यह है कि इस नियम से एक अपवाद की तरह लग रहा है - अगर अमूर्त वर्ग केवल एक डिफ़ॉल्ट निर्माता को परिभाषित करता है, तो उपवर्ग एक निर्माता को लागू करने की जरूरत नहीं है: यह कानूनी है:

public abstract class A { 
    public A() {} 
} 

public class B extends A {} 

तो हम new B() पर कॉल करके B बना सकते हैं - लेकिन ध्यान दें, कि हम अभी भीB बनाएं और A नहीं। और, फिर से, इससे कोई फर्क नहीं पड़ता कि A में निर्माता सार्वजनिक या संरक्षित है या नहीं। यह सिर्फ निजी नहीं होना चाहिए, लेकिन संकलक नोटिस करेंगे और शिकायत ...

असल में हम B जो एक सरल super() कॉल करता है पर एक "अदृश्य" सार्वजनिक डिफ़ॉल्ट निर्माता आह्वान ...

-8

आप हो सकता है एक सार्वजनिक कन्स्ट्रक्टर यदि आप उप-वर्ग में एक निर्माता में परिभाषित नहीं करते हैं। उदाहरण

abstract class Animal { 
    String name; 
    public void Animal(String name) { 
     this.name = name; 
    } 
} 


class Cat extends Animal{ 
    public String sayMayName() { 
     return this.name; 
    } 
} 

myCat = new Cat("tester"); 

name = myCat.sayMyName(); 

अगर कोई निर्माता, माता पिता के वर्ग निर्माता बुलाया जाएगा परिभाषित किया गया है अगर यह सार्वजनिक नहीं है यह काम नहीं करेगा। यह मुझे लगता है कि फैक्ट्री पैटर्न के साथ अधिक सुंदरता से किया गया है, लेकिन मैंने इसे PHP में अभ्यास में इस्तेमाल किया और यह ठीक काम करता है।

+3

यह जावा में काम नहीं करता है। साथ ही, आप 'Animal' कक्षा में एक कन्स्ट्रक्टर को परिभाषित नहीं कर रहे हैं, क्योंकि आप रिटर्न प्रकार निर्दिष्ट करते हैं (' शून्य ')। –

+2

यह संकलित नहीं होगा - 'कैटर' में एक कन्स्ट्रक्टर * आवश्यक * है क्योंकि 'एनिमल' में एक (डिफ़ॉल्ट नहीं) कन्स्ट्रक्टर है ('सार्वजनिक शून्य पशु (स्ट्रिंग नाम)' वैसे भी एक कन्स्ट्रक्टर नहीं है) –

+0

यह केवल काम करेगा नो-एर्ग कन्स्ट्रक्टर के साथ। इसे आज़माएं, आपका कोड संकलित नहीं होगा। लेकिन अंतर्निहित डिफॉल्ट कन्स्ट्रक्टर हमेशा क्लास की दृश्यता रखता है, भले ही सुपरक्लस कन्स्ट्रक्टर क्या है। – biziclop

-7

मुझे एक विचित्र कहो, लेकिन ... मुझे एक अमूर्त वर्ग में एक निर्माता के लिए कम से कम एक उपयोग दिखाई देता है।

यह है कि यह निर्दिष्ट करने के लिए कि कन्स्ट्रक्टर पैरामीटर कैसा दिखता है।

एक सार रचनाकार निर्दिष्ट करें (इस प्रकार कक्षा सार बनाते हैं)। व्युत्पन्न वर्गों को अमूर्त स्थिति खोने के लिए अपने विशिष्ट हस्ताक्षर के साथ इस कन्स्ट्रक्टर को कार्यान्वित करना होगा।

मुझे अनिवार्य कन्स्ट्रक्टर हस्ताक्षर निर्दिष्ट करने का कोई अन्य तरीका नहीं है (यदि आप करते हैं तो मेरी सहायता करें)।

+3

बनाया गया था कन्स्ट्रक्टर 'संरक्षित' बनाना अभी भी आपको "निर्दिष्टकर्ता कंट्रोल पैरामीटर जैसा दिखाना है" निर्दिष्ट करने की अनुमति देता है। – Raedwald

+0

सच है, लेकिन ऐसा करने के लिए व्युत्पन्न कक्षा को सुपर() या जोखिम वाले लापता चरणों को कॉल करने की आवश्यकता होती है जो हो सकता है। सार स्पष्ट करता है कि यह केवल हस्ताक्षर है, कोई कार्यान्वयन नहीं है। - अगर इंटरफेस को कन्स्ट्रक्टर हस्ताक्षर निर्दिष्ट करने की अनुमति दी जाती है तो यह सबसे अच्छा होगा। लेकिन चूंकि वे नहीं करते हैं, इसलिए मैं सारणी कक्षाओं को अगली सबसे अच्छी बात मानता हूं। – foo

+3

आप 'सुपर' को कॉल करने से नहीं बच सकते हैं। इसे स्पष्ट रूप से कहा जाता है यदि आप इसे स्पष्ट रूप से कॉल नहीं करते हैं। – Raedwald

0

दृश्यता भी जावाडोक में दिखाया गया है (यदि यह कुछ दृश्यता स्तर को बाहर करने के लिए चुना गया है) को भी प्रभावित करता है। चूंकि इससे कोई फर्क नहीं पड़ता, यह एक अमूर्त वर्ग के सार्वजनिक निर्माता के लिए उपयोग हो सकता है।

यदि आप कोई कन्स्ट्रक्टर प्रदान नहीं करते हैं, तो क्लास सार्वजनिक होने पर डिफ़ॉल्ट कन्स्ट्रक्टर सार्वजनिक है। सुरक्षित कन्स्ट्रक्टर को मजबूर करने के बजाय, सबसे आसान विकल्प यह अनुमति देना होगा।

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

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