क्लास में कंस्ट्रक्टर को निजी बनाने का क्या फायदा है?


134

हमें कक्षा में कंस्ट्रक्टर को निजी क्यों बनाना चाहिए? जैसा कि हमें सार्वजनिक होने के लिए हमेशा निर्माता की आवश्यकता होती है।

जवाबों:


129

कुछ कारण जहां आपको निजी कंस्ट्रक्टर की आवश्यकता हो सकती है:

  1. कंस्ट्रक्टर को केवल क्लास के अंदर ही स्थिर फैक्ट्री पद्धति से एक्सेस किया जा सकता है। सिंगलटन भी इसी श्रेणी का हो सकता है।
  2. एक उपयोगिता वर्ग , जिसमें केवल स्थैतिक विधियाँ हैं।

9
मैंने उपयोगिता वर्ग के लिए एक निजी कंस्ट्रक्टर बनाने की भी जहमत नहीं उठाई होगी।
पेटेश

16
@Patesh: यह आपका निर्णय है। अन्य (ओं) और मैं बल्कि एक लाइन निजी कंस्ट्रक्टर को छोड़ने की तुलना में उपयोगिता वर्ग की तात्कालिकता को रोकेंगे।
नंद

1
कुछ प्रोग्रामिंग भाषाओं (विशेष रूप से जावा) में यह विरासत को भी रोकता है
dfa

9
@dfa: वंशानुक्रम को रोकने के लिए, आपको finalकक्षा स्तर पर रखना होगा । निजी कंस्ट्रक्टर को लगाना इस कारण बहुत बेकार है।
नंद

3
@Will: यदि आप प्रतिबिंब का उपयोग नहीं करते हैं। कंस्ट्रक्टर्स को निजी घोषित करना तात्कालिकता (प्रतिबिंब को रोकना) को रोकने के लिए है, लेकिन उपवर्ग को रोकना एक दुष्प्रभाव है, न कि इरादे। इसके लिए उपयुक्त उपकरण वर्ग घोषित कर रहा है final। यह वही है जो सूर्य ने स्ट्रिंग वर्ग के लिए किया था, और एपीआई का एक उचित हिस्सा जिसे बढ़ाया नहीं जाना चाहिए।
BobMcGee

96

एक निजी कंस्ट्रक्टर प्रदान करके आप कक्षा के उदाहरणों को इस बहुत ही वर्ग के अलावा किसी भी स्थान पर बनाए जाने से रोकते हैं। इस तरह के कंस्ट्रक्टर प्रदान करने के लिए कई उपयोग के मामले हैं।

A. आपकी कक्षा के उदाहरण एक staticविधि में बनाए गए हैं । staticविधि तो के रूप में घोषित किया जाता है public

class MyClass()
{
private:
  MyClass() { }

public:
  static MyClass * CreateInstance() { return new MyClass(); }
};

B. आपकी कक्षा एक सिंगलटन है । इसका अर्थ है, आपकी कक्षा का एक से अधिक उदाहरण कार्यक्रम में मौजूद नहीं है।

class MyClass()
{
private:
  MyClass() { }

public:
  MyClass & Instance()
  {
    static MyClass * aGlobalInst = new MyClass();
    return *aGlobalInst;
  }
};

सी। (केवल आगामी सी ++ 0x मानक पर लागू होता है) आपके पास कई निर्माता हैं। उनमें से कुछ घोषित हैं public, अन्य private। कोड के आकार को कम करने के लिए, सार्वजनिक निर्माणकर्ता निजी बिल्डरों को 'कॉल' करते हैं जो बदले में सभी काम करते हैं। आपके publicकंस्ट्रक्टरों को इस तरह से डेलिगेटिंग कंस्ट्रक्टर कहा जाता है :

class MyClass
{
public:
  MyClass() : MyClass(2010, 1, 1) { }

private:
  MyClass(int theYear, int theMonth, int theDay) { /* do real work */ }
};

डी। आप वस्तु की नकल को सीमित करना चाहते हैं (उदाहरण के लिए, साझा संसाधन का उपयोग करने के कारण):

class MyClass
{
  SharedResource * myResource;

private:
  MyClass(const MyClass & theOriginal) { }
};

ई। आपकी कक्षा एक उपयोगिता वर्ग है । इसका मतलब है, इसमें केवल staticसदस्य शामिल हैं। इस स्थिति में, प्रोग्राम में कोई ऑब्जेक्ट इंस्टेंस नहीं बनाया जाना चाहिए।


3
ज्यादातर मामलों में आप ऑब्जेक्ट को कॉपी करने से रोकना चाहेंगे। इसलिए आप निजी कॉपी कंस्ट्रक्टर के लिए कार्यान्वयन प्रदान नहीं करेंगे।
frast

google c ++ स्टाइल गाइड से (सूची में एक और उदाहरण नहीं बल्कि आम है) -> यदि आपको कंस्ट्रक्टर में काम करने की ज़रूरत है "एक कारखाने के कार्य पर विचार करें [और निर्माता को निजी बनाने]" (वर्ग ब्रेसिज़ में पाठ मेरे द्वारा लिखा गया है) )
ट्रेवर बॉयड स्मिथ

12

एक "बैक डोर" को छोड़ने के लिए जो किसी अन्य मित्र वर्ग / फ़ंक्शन को उपयोगकर्ता के लिए निषिद्ध तरीके से ऑब्जेक्ट बनाने की अनुमति देता है। एक उदाहरण जो दिमाग में आता है, वह एक कंटेनर होगा जो एक इटेटर (C ++) का निर्माण करेगा:

Iterator Container::begin() { return Iterator(this->beginPtr_); }
// Iterator(pointer_type p) constructor is private,
//     and Container is a friend of Iterator.

क्या यह काफी अलग है, टेरी? ;)
एमिल कॉर्मियर

अच्छा उत्तर। प्रतिबिंब का उल्लेख क्यों नहीं किया गया है, क्योंकि यह कुछ उपयोगकर्ता को पूरा करने के लिए एक अवसर नहीं है?
BobMcGee

@ याकूब: आपको मुझे उस एक पर प्रकाश डालना होगा, क्योंकि मैं मुख्य रूप से एक सी ++ लड़का हूं और प्रतिबिंब वास्तव में सी ++ शब्दावली में नहीं है। ;)
एमिल कॉर्मियर

3
कोई भी इसे पढ़ने नहीं जा रहा है, लेकिन यहाँ जाता है: मुझे इस पर एक-दो बार उतारा गया है। परेशान या कुछ भी नहीं, लेकिन (सीखने के लिए) मैं जानना चाहता हूं कि यह बुरा क्यों है? कंटेनर के डेटा को एक्सेस करने के लिए डेटा के साथ एक इटरेटर का निर्माण कैसे किया जा सकता है?
एमिल कॉर्मियर

2
@EmileCormier, मुझे लगता है कि आपने गलत तरीके से वोट डाला क्योंकि C ++ सीखने वाले लोगों को बार-बार कहा जाता है: "मित्र घोषणाओं से बचें"। यह सलाह अनुभवहीन C ++ प्रोग्रामर के उद्देश्य से लगती है जो अन्यथा उपयोग कर सकते हैं friendजहां यह वारंट नहीं है - और ऐसे बहुत सारे मामले हैं जहां यह एक बुरा विचार है। अफसोस की बात है कि संदेश बहुत अच्छी तरह से प्राप्त किया गया है, और कई डेवलपर्स कभी भी भाषा को अच्छी तरह से समझने के लिए कभी नहीं सीखते हैं कि कभी-कभी उपयोग friendकेवल स्वीकार्य नहीं है, लेकिन बेहतर है । आपका उदाहरण सिर्फ इस तरह का मामला था। जानबूझकर मजबूत कपलिंग कोई अपराध नहीं है, यह एक डिजाइन निर्णय है।
evadeflow

10

हर कोई सिंगलटन की बात पर अड़ा हुआ है, वाह।

अन्य बातें:

  • स्टैक पर अपनी कक्षा बनाने से लोगों को रोकें; फैक्ट्री मेथड के माध्यम से प्राइवेट कंस्ट्रक्टर और केवल बैक पॉइंट को बनाते हैं।
  • कक्षा के कॉपियों का निर्माण रोकना (निजी कॉपी कंस्ट्रक्टर)

8

यह एक रचनाकार के लिए बहुत उपयोगी हो सकता है जिसमें सामान्य कोड शामिल है; निजी कंस्ट्रक्टरों को 'यह (...);' का उपयोग करके अन्य कंस्ट्रक्टरों द्वारा बुलाया जा सकता है। अंकन। एक निजी (या संरक्षित) कंस्ट्रक्टर में सामान्य आरंभीकरण कोड बनाकर, आप यह भी स्पष्ट रूप से स्पष्ट कर रहे हैं कि इसे केवल निर्माण के दौरान कहा जाता है, जो कि ऐसा नहीं है यदि यह केवल एक विधि है:

public class Point {
   public Point() {
     this(0,0); // call common constructor
   }
   private Point(int x,int y) {
     m_x = x; m_y = y;
   }
};

3

कुछ उदाहरण हैं जहां आप सार्वजनिक निर्माणकर्ता का उपयोग नहीं करना चाहते हैं; उदाहरण के लिए यदि आप एकल वर्ग चाहते हैं।

यदि आप 3 पार्टियों द्वारा उपयोग की जाने वाली असेंबली लिख रहे हैं, तो कई आंतरिक वर्ग हो सकते हैं जिन्हें आप केवल अपनी असेंबली द्वारा बनाया जाना चाहते हैं और न कि आपके असेंबली के उपयोगकर्ताओं द्वारा इंस्टेंट किया जाए।


3

यह सुनिश्चित करता है कि आप (निजी कंस्ट्रक्टर के साथ वर्ग) नियंत्रण करते हैं कि कंट्रक्टर को कैसे कहा जाता है।

एक उदाहरण: क्लास पर एक स्थिर फैक्टरी विधि ऑब्जेक्ट्स को वापस कर सकती है क्योंकि फैक्टरी विधि उन्हें आवंटित करने के लिए धोखा देती है (उदाहरण के लिए एक सिंगलटन फैक्ट्री की तरह)।


@Skilldrick: एक उदाहरण यह होगा कि आप किसी वर्ग को केवल आबंटित किए जाने के लिए बाध्य कर सकते हैं।
डर्क

@dirk मैंने अपनी टिप्पणी हटा दी है क्योंकि यह अब प्रासंगिक नहीं है।
स्किलड्रिक

3

हमारे पास निजी कंस्ट्रक्टर भी हो सकते हैं, केवल विशिष्ट वर्ग (सुरक्षा कारणों से) द्वारा ऑब्जेक्ट के निर्माण को आगे बढ़ाने के लिए।

इसे करने का एक तरीका मित्र वर्ग है।

C ++ उदाहरण:

class ClientClass;
class SecureClass 
{
  private:
    SecureClass();   // Constructor is private.
    friend class ClientClass;  // All methods in 
                               //ClientClass have access to private
                               // &   protected methods of SecureClass.
};

class ClientClass
{
public:
    ClientClass();
    SecureClass* CreateSecureClass()
     { 
           return (new SecureClass());  // we can access 
                                        // constructor of 
                                        // SecureClass as 
                                        // ClientClass is friend 
                                        // of SecureClass.
     }
};

नोट: नोट: केवल क्लाइंटक्लास (चूंकि यह सिक्योरक्लास का दोस्त है) सिक्योरक्लास के कंस्ट्रक्टर को कॉल कर सकता है।


2

2

जब आप उपयोगकर्ताओं को इस वर्ग के उदाहरण नहीं बनाना चाहते हैं या इस वर्ग को इनहेरिट करने वाले वर्ग का निर्माण करना चाहते हैं, जैसे java.lang.math, इस पैकेज में staticसभी फ़ंक्शन हैं, तो सभी कार्यों को एक इंस्टेंस mathबनाए बिना बुलाया जा सकता है , इसलिए निर्माणकर्ता को स्थिर के रूप में घोषित किया जाता है। ।


1

अगर यह निजी है, तो आप इसे कॉल नहीं कर सकते ==> आप क्लास को तुरंत नहीं कर सकते। कुछ मामलों में उपयोगी, एक सिंगलटन की तरह।

यहां एक चर्चा और कुछ और उदाहरण हैं


1

मैंने आपसे उसी मुद्दे को संबोधित करते हुए एक प्रश्न देखा।

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


1

आपको नहीं करना चाहिए कंस्ट्रक्टर को निजी बनाना । अवधि। इसे संरक्षित करें, ताकि जरूरत पड़ने पर आप कक्षा का विस्तार कर सकें।

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

यदि यह एक उपयोगिता वर्ग है, तो विस्तार को रोकने के लिए सरल, अधिक सही और अधिक सुरुचिपूर्ण समाधान पूरे वर्ग "स्थिर फाइनल" को चिह्नित करना है। यह केवल कंस्ट्रक्टर प्राइवेट को चिह्नित करने के लिए कोई अच्छा काम नहीं करता है; एक वास्तव में निर्धारित उपयोगकर्ता हमेशा कंस्ट्रक्टर प्राप्त करने के लिए प्रतिबिंब का उपयोग कर सकता है।

मान्य उपयोग:

  • एक अच्छा उपयोग की protected कंस्ट्रक्टर का स्टेटिक फ़ैक्टरी विधियों के उपयोग को बाध्य करना है, जो आपको इंस्टेंटेशन या पूल को सीमित करने और महंगे संसाधनों (डीबी कनेक्शन, देशी संसाधनों) का पुन: उपयोग करने की अनुमति देता है।
  • एकल (आमतौर पर अच्छा अभ्यास नहीं, लेकिन कभी-कभी आवश्यक होता है)

2
मेरे अनुभव में कोई पूर्ण सत्य नहीं है, यहां तक ​​कि अगर स्थिति मांगती है तो गोटो का भी उपयोग किया जा सकता है। बैड और ईविल तरीके हैं, लेकिन जैसा कि मार्शल क्लाइन इसे कहते हैं, कभी-कभी आपको बुराइयों के बीच चयन करने की आवश्यकता होती है। parashift.com/c++-faq-lite/big-picture.html#faq-6.15 निजी कंस्ट्रक्टरों के लिए, वे आवश्यक हैं और आपके लिए खराब भी नहीं हैं। इसका सिर्फ यह मतलब है कि आपके उपवर्गों सहित किसी को भी इसका उपयोग नहीं करना चाहिए।
डमरक

गॉटोस के पास अपना स्थान है, सच है, लेकिन एक निर्माता के निजी लाभ को चिह्नित करने से आपको कुछ भी नहीं मिलता है, लेकिन सड़क के नीचे परेशानी होती है। मैंने अपनी पोस्ट को और अधिक पूरी तरह से समझाने के लिए संपादित किया है।
BobMcGee

यह नहीं है मतलब प्रतिलिपि निर्माण या डिफ़ॉल्ट निर्माण कुछ वर्गों के लिए। C ++ में आप इसे परिभाषित किए बिना एक निजी ctor घोषित करके इसका संकेत देते हैं (जो ऑपरेटर = के लिए भी सामान्य है)।

जावा जेआईटी और जीडब्ल्यूटी जैसे संकलक अनुकूलन वास्तव में निजी निर्माणकर्ताओं का उपयोग करते हैं: तात्कालिकता के दायरे को सीमित करने और अपने कोड को आगे बढ़ाने / बेहतर बनाने के लिए एक बेहतर काम करते हैं।
अजाक्स

1

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

#include<iostream>
using namespace std;
class singletonClass
{


    static int i;
    static singletonClass* instance;
public:


    static singletonClass* createInstance()
    {


        if(i==0)
        {

            instance =new singletonClass;
            i=1;

        }

        return instance;

    }
    void test()
    {

        cout<<"successfully created instance";
    }
};

int singletonClass::i=0;
singletonClass* singletonClass::instance=NULL;
int main()
{


    singletonClass *temp=singletonClass::createInstance();//////return instance!!!
    temp->test();
}

फिर से यदि आप 10 तक ऑब्जेक्ट निर्माण को सीमित करना चाहते हैं तो निम्नलिखित का उपयोग करें

#include<iostream>
using namespace std;
class singletonClass
{


    static int i;
    static singletonClass* instance;
public:


    static singletonClass* createInstance()
    {


        if(i<10)
        {

            instance =new singletonClass;
            i++;
            cout<<"created";

        }

        return instance;

    }
};

int singletonClass::i=0;
singletonClass* singletonClass::instance=NULL;
int main()
{


    singletonClass *temp=singletonClass::createInstance();//return an instance
    singletonClass *temp1=singletonClass::createInstance();///return another instance

}

धन्यवाद


1

आपके पास एक से अधिक निर्माता हो सकते हैं। यदि आप स्पष्ट रूप से एक प्रदान नहीं करते हैं तो C ++ एक डिफ़ॉल्ट कंस्ट्रक्टर और एक डिफ़ॉल्ट कॉपी कंस्ट्रक्टर प्रदान करता है। मान लीजिए कि आपके पास एक वर्ग है जो केवल कुछ पैरामीटर वाले कंस्ट्रक्टर का उपयोग करके बनाया जा सकता है। हो सकता है कि इसने वैरिएबल को इनिशियलाइज़ किया हो। यदि कोई उपयोगकर्ता उस निर्माता के बिना इस वर्ग का उपयोग करता है, तो वे समस्याओं का कोई अंत नहीं कर सकते हैं। एक अच्छा सामान्य नियम: यदि डिफ़ॉल्ट कार्यान्वयन मान्य नहीं है, तो डिफ़ॉल्ट और कॉपी कंस्ट्रक्टर दोनों को निजी बनाएं और कार्यान्वयन प्रदान न करें:

class C
{
public:
    C(int x);

private:
    C();
    C(const C &);
};

उपयोगकर्ताओं को डिफ़ॉल्ट निर्माता के साथ ऑब्जेक्ट का उपयोग करने से रोकने के लिए कंपाइलर का उपयोग करें जो मान्य नहीं हैं।


2
जब आप एक डिफ़ॉल्ट निर्माता को निर्दिष्ट किए बिना एक गैर डिफ़ॉल्ट निर्माता प्रदान करते हैं, तो डिफ़ॉल्ट निर्माता मौजूद नहीं होता है। इसे बनाने और इसे निजी बनाने की आवश्यकता नहीं है।
TT_

0

प्रभावी जावा से उद्धरण , आपके पास निजी निर्माणकर्ता के साथ उपयोगिता वर्ग रखने के लिए एक वर्ग हो सकता है जो स्थिरांक (स्थिर अंतिम क्षेत्रों के रूप में) को परिभाषित करता है।

( संपादित करें: टिप्पणी के अनुसार यह कुछ ऐसा है जो केवल जावा के साथ लागू हो सकता है, मैं इस बात से अनजान हूँ कि यह निर्माण अन्य OO भाषाओं में लागू है / आवश्यक है (C ++ कहें)

नीचे के रूप में एक उदाहरण:

public class Constants {
    private Contants():

    public static final int ADDRESS_UNIT = 32;
    ...
}

EDIT_1 : फिर से, नीचे स्पष्टीकरण जावा में लागू है: (और पुस्तक से संदर्भित, प्रभावी जावा )

उपयोगिता वर्ग की एक तात्कालिकता जैसे नीचे, हालांकि हानिकारक नहीं है, किसी भी उद्देश्य की सेवा नहीं करता है क्योंकि वे तात्कालिक होने के लिए डिज़ाइन नहीं किए गए हैं।

उदाहरण के लिए, मान लें कि क्लास कांस्टेंट के लिए कोई निजी कंस्ट्रक्टर नहीं है। नीचे की तरह एक कोड चंक वैध है, लेकिन कॉन्स्टेंट वर्ग के उपयोगकर्ता के इरादे को बेहतर ढंग से व्यक्त नहीं करता है

unit = (this.length)/new Constants().ADDRESS_UNIT;

जैसे कोड के विपरीत

unit = (this.length)/Constants.ADDRESS_UNIT;

इसके अलावा, मुझे लगता है कि एक निजी कंस्ट्रक्टर कॉन्स्टेंट्स (कहना) वर्ग के डिजाइनर के इरादे को बेहतर बताता है।

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

एक शीर्ष स्तर के स्थिर वर्ग को चिह्नित नहीं कर सकता है और यहां तक ​​कि एक अंतिम वर्ग को तत्काल किया जा सकता है।


2
लेकिन C ++ में आपको इसके लिए क्लास की जरूरत नहीं है। यदि कोई वस्तु ऑब्जेक्ट के अंदर डेटा पर निर्भर नहीं करती है, तो इसे नि: शुल्क फ़ंक्शन और मुफ्त चर के रूप में लिखें। एनकैप्सुलेशन चाहते हैं? एक नाम स्थान का उपयोग करें।
दरामारक

@daramarak: धन्यवाद, मुझे C ++ के साथ कोई अनुभव नहीं है। मैंने उत्तर को प्रतिबिंबित करने के लिए अद्यतन किया कि यह केवल जावा में लागू होता है
sateesh

2
यदि आपकी वस्तु सिर्फ स्थैतिक चर अतिक्रमण कर रही है, तो तात्कालिकता को सीमित क्यों करें? कंस्ट्रक्टर के बारे में कुछ भी क्यों निर्दिष्ट करें? अगर यह तुरंत है तो यह कोई नुकसान नहीं करेगा। लगता है कि आप कक्षा को स्थिर और अंतिम घोषित करने के समान परिणाम प्राप्त कर सकते हैं।
BobMcGee

@ याकूबसीजी, आपकी टिप्पणी के लिए धन्यवाद। इसने मुझे जो पोस्ट किया है उसके बारे में और अधिक सोचने (और संदर्भित) करने के लिए बनाया है। मैंने निजी कंस्ट्रक्टर की उपयोगिता के बारे में कुछ और तर्क जोड़ने के लिए अपना उत्तर संपादित किया है।
सप्तेश

0

उपयोगिता वर्ग में निजी निर्माणकर्ता हो सकते हैं। वर्गों के उपयोगकर्ताओं को इन वर्गों को तुरंत करने में सक्षम नहीं होना चाहिए:

public final class UtilityClass {
    private UtilityClass() {}

    public static utilityMethod1() {
        ...
    }
}

1
यदि उपयोगिता वर्ग को त्वरित किया जाता है तो यह क्यों मायने रखता है? यह सब वह करता है जिसमें कोई फ़ील्ड नहीं है और मेमोरी के कुछ बाइट्स खाते हैं।
BobMcGee

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

@ थोबमसीजी: स्पष्ट रूप से एक वर्ग को डिजाइन करना जो काम करता है और अन्य लोगों द्वारा उपयोग किए जाने वाले वर्ग को डिजाइन करना अलग चीजें हैं। जो लोग एपीआई विकास में काम करते हैं (जैसे कि सन लोग या Google संग्रह आदमी) किसी को यह कहने की कोशिश करेंगे कि उपयोगिता वर्ग में निजी निर्माण बेकार है।
नंद

@gpampara: अपने वर्ग के फाइनल की घोषणा करने से लोगों को उपवर्ग करने से रोकता है। यह वही है जो सूर्य ने स्ट्रिंग वर्ग के लिए किया था। @ नंदा: एक उपयोगिता वर्ग को परिभाषित कंस्ट्रक्टर की आवश्यकता नहीं है । यदि आप नहीं चाहते हैं कि यह एक्स्टेंसिबल हो, तो इसे "फाइनल" का उपयोग न करने की घोषणा करें।
BobMcGee

1
@ याकूबसीजी: आप सूर्य से उदाहरण देखना पसंद करते हैं। फिर सूर्य से इस उपयोगिता वर्ग संग्रह की जाँच करें: docjar.com/html/api/java/util/Collections.avaava.html । यह वास्तव में निजी कंस्ट्रक्टर का उपयोग कर रहा है।
नंद

0

आप एक वर्ग को स्वतंत्र रूप से तत्काल किए जाने से रोकना चाह सकते हैं। एक उदाहरण के रूप में सिंगलटन डिजाइन पैटर्न देखें। विशिष्टता की गारंटी देने के लिए, आप किसी को भी इसका उदाहरण नहीं दे सकते हैं :-)


0

एक महत्वपूर्ण उपयोग सिंगलटन वर्ग में है

class Person
{
   private Person()
   {
      //Its private, Hense cannot be Instantiated
   }

   public static Person GetInstance()
   {
       //return new instance of Person
       // In here I will be able to access private constructor
   }
};

यह भी उपयुक्त है, यदि आपकी कक्षा में केवल स्थिर विधियाँ हैं। अर्थात किसी को भी आपकी कक्षा को तुरंत करने की आवश्यकता नहीं है


यह ध्यान दिया जाना चाहिए कि सिंगलटन को बहुत से लोग "विरोधी पैटर्न" मानते हैं और इसे लागू करने के निर्णय को हल्के ढंग से नहीं किया जाना चाहिए। एक सामान्य विकल्प निर्भरता इंजेक्शन है।
माइकल आरोन सफ़्यान

सिंगलटॉन एक प्रतिमान नहीं है। हालाँकि, पैटर्न का अधिक उपयोग (क्योंकि इसके उपयोग की जानकारी का अभाव) अच्छा नहीं है। यह ध्यान दिया जाना चाहिए कि इसका एक GOF पैटर्न है।
SysAdmin

0

यह वास्तव में एक स्पष्ट कारण है: आप एक वस्तु का निर्माण करना चाहते हैं, लेकिन निर्माणकर्ता के भीतर इसे (इंटरफ़ेस की अवधि में) करना व्यावहारिक नहीं है।

Factoryउदाहरण काफी स्पष्ट है, मुझे का प्रदर्शन करते हैं Named Constructorमुहावरा।

कहें कि मेरे पास एक वर्ग है Complexजो एक जटिल संख्या का प्रतिनिधित्व कर सकता है।

class Complex { public: Complex(double,double); .... };

सवाल यह है: क्या निर्माता वास्तविक और काल्पनिक भागों की अपेक्षा करता है, या क्या यह आदर्श और कोण (ध्रुवीय निर्देशांक) की अपेक्षा करता है?

मैं इंटरफ़ेस को आसान बनाने के लिए बदल सकता हूं:

class Complex
{
public:
  static Complex Regular(double, double = 0.0f);
  static Complex Polar(double, double = 0.0f);
private:
  Complex(double, double);
}; // class Complex

इसे Named Constructorमुहावरा कहा जाता है : वर्ग केवल खरोंच से बनाया जा सकता है यह स्पष्ट रूप से कहा जाता है कि हम किस निर्माणकर्ता का उपयोग करना चाहते हैं।

यह कई निर्माण विधियों का एक विशेष मामला है। डिजाइन पैटर्न का निर्माण वस्तु के लिए तरीके का एक अच्छी संख्या प्रदान करते हैं: Builder, Factory, Abstract Factory, ... और एक निजी निर्माता यह सुनिश्चित करेंगे कि उपयोगकर्ता ठीक से विवश है।


0

बेहतर उपयोग के अलावा…

विधि ऑब्जेक्ट पैटर्न को लागू करने के लिए , जिसे मैं संक्षेप में प्रस्तुत करूंगा:

"निजी निर्माता, सार्वजनिक स्थैतिक विधि"
"कार्यान्वयन के लिए उद्देश्य, इंटरफ़ेस के लिए कार्य"

यदि आप किसी ऑब्जेक्ट का उपयोग करके फ़ंक्शन को कार्यान्वित करना चाहते हैं, और ऑब्जेक्ट एक-ऑफ संगणना (एक विधि कॉल द्वारा) करने से बाहर उपयोगी नहीं है, तो आपके पास एक थ्रॉवे ऑब्जेक्ट है । आप इस सामान्य विरोधी प्रतिमान को रोकते हुए वस्तु निर्माण और विधि कॉल को एक स्थिर विधि में संलग्न कर सकते हैं:

z = new A(x,y).call();

... इसे (नाम स्थान) फ़ंक्शन कॉल के साथ प्रतिस्थापित करना:

z = A.f(x,y);

कॉल करने वाले को यह जानने या देखभाल करने की आवश्यकता नहीं है कि आप आंतरिक रूप से एक ऑब्जेक्ट का उपयोग कर रहे हैं, एक क्लीनर इंटरफ़ेस उपज है, और ऑब्जेक्ट के चारों ओर लटका हुआ ऑब्जेक्ट या गलत उपयोग से कचरा को रोकते हैं।

उदाहरण के लिए, आप तरीकों के पार एक अभिकलन को तोड़ने के लिए चाहते हैं, तो foo, barहै, और zorkमें और कार्यों से बाहर है, तो आप इसे लागू कर सकता है के रूप में इस प्रकार कई मान पास करने के बिना शेयर राज्य के लिए उदाहरण के लिए,:

class A {
  public static Z f(x, y) {
    A a = new A(x, y);
    a.foo();
    a.bar();
    return a.zork();
  }

  private A(X x, Y y) { /* ... */ };
}

यह विधि ऑब्जेक्ट पैटर्न स्मॉलटाकल बेस्ट प्रैक्टिस पैटर्न , केंट बेक, पेज 34-37 में दी गई है, जहां यह एक रिफैक्टिंग पैटर्न का अंतिम चरण है, जो समाप्त होता है:

  1. मूल विधि के मापदंडों और रिसीवर के साथ निर्मित, नए वर्ग का एक उदाहरण बनाने वाले मूल विधि को बदलें, और "कंपोज" को आमंत्रित करें।

यह यहां अन्य उदाहरणों से काफी भिन्न है: वर्ग तात्कालिक है (एक उपयोगिता वर्ग के विपरीत), लेकिन उदाहरण निजी हैं (कारखाने के तरीकों के विपरीत, सिंगललेट्स आदि सहित), और स्टैक पर रह सकते हैं, क्योंकि वे कभी बच नहीं जाते हैं।

यह पैटर्न बोतलों-अप ओओपी में बहुत उपयोगी है, जहां वस्तुओं का उपयोग निम्न-स्तरीय कार्यान्वयन को सरल बनाने के लिए किया जाता है, लेकिन जरूरी नहीं कि बाहरी रूप से उजागर हो, और टॉप-डाउन ओओपी के साथ विरोधाभास जो अक्सर प्रस्तुत किया जाता है और उच्च-स्तरीय इंटरफेस के साथ शुरू होता है।


0

कभी-कभी उपयोगी होता है यदि आप नियंत्रित करना चाहते हैं कि किसी वस्तु के कैसे और कब (और कितने) उदाहरण बनते हैं।

दूसरों के बीच, पैटर्न में उपयोग किया जाता है:

Singleton pattern
Builder pattern

एक निजी निर्माणकर्ता एक अपरिवर्तनीय वस्तु में कैसे उपयोगी है? सृजन के बाद किसी वस्तु में परिवर्तन को रोकने के बारे में अपरिवर्तनीयता है , जबकि निजी निर्माणकर्ता सृजन को रोकने के बारे में हैं ।
निल्स वॉन बर्थ

0

निजी निर्माणकर्ताओं के उपयोग से डोमेन-संचालित डिज़ाइन के सामने पठनीयता / स्थिरता को बढ़ाया जा सकता है। "Microsoft .NET - एंटरप्राइज़, द्वितीय संस्करण के लिए आर्किटेकिंग एप्लिकेशन" से:

var request = new OrderRequest(1234);

उद्धरण, "यहां दो समस्याएं हैं। सबसे पहले, जब कोड को देखते हैं, तो शायद ही कोई अनुमान लगा सकता है कि क्या चल रहा है। ऑर्डरअर्सपेस्ट का एक उदाहरण बनाया जा रहा है, लेकिन क्यों और किस डेटा का उपयोग किया जा रहा है? 1234 क्या है? यह दूसरी समस्या की ओर जाता है: आप बंधे हुए संदर्भ की सर्वव्यापी भाषा का उल्लंघन कर रहे हैं। भाषा शायद कुछ इस तरह से कहती है: एक ग्राहक एक आदेश अनुरोध जारी कर सकता है और एक खरीद आईडी निर्दिष्ट करने की अनुमति दी जाती है। यदि यह मामला है, तो यहां एक नया आदेश प्राप्त करने का बेहतर तरीका है। : "

var request = OrderRequest.CreateForCustomer(1234);

कहाँ पे

private OrderRequest() { ... }

public OrderRequest CreateForCustomer (int customerId)
{
    var request = new OrderRequest();
    ...
    return request;
}

मैं हर एक वर्ग के लिए इसकी वकालत नहीं कर रहा हूं, लेकिन उपरोक्त डीडीडी परिदृश्य के लिए मुझे लगता है कि यह एक नई वस्तु के प्रत्यक्ष निर्माण को रोकने के लिए बिल्कुल सही समझ में आता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.