2013-08-03 7 views
6

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

public class Person{ 
    private String name; 

    public Person(String name){ 
     //is this right, seems like the whole encapsulation purpose is defeated 
     this.name = name; 

     //shouldn't this be used 
     setName(name); 
    } 

    public String getName(){ 
     return this.name; 
    } 

    public void setName(String name){ 
     this.name = name; 
    } 
} 
+7

मेरा मानना ​​है कि चर बनाने के उद्देश्य से उन्हें ** अन्य ** कक्षाओं से प्रत्यक्ष हेरफेर से अलग करना है। –

+2

इसके अतिरिक्त, 'यह' कीवर्ड गेटर के लिए आवश्यक नहीं है; इसका उपयोग तब किया जाता है जब अस्पष्टता होती है (यानी यदि एक ही स्कोप में "नाम" नामक एक और चर होता है) – ataulm

उत्तर

5

आप कुछ भी याद नहीं कर रहे हैं। आप जो करते हैं वह पूरी तरह से आपकी स्थिति पर निर्भर करता है। हालांकि, इस पर विचार करें:

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

public class Example { 
    private int value; 
    public Example() { 
    } 
    public final int getValue() { 
     return value; 
    } 
    public final void setValue (int value) throws IllegalArgumentException { 
     if (value < 0 || value > 10) 
      throw new IllegalArgumentException("Value is out of range."); 
    } 
} 

यहाँ, setValue () यह सुनिश्चित करने के लिए 'मान' को मान्य करता है कि यह नियमों पर चिपक जाता है। हमारे पास एक आविष्कार है जो कहता है "एक उदाहरण सीमा मूल्य से बाहर नहीं होगा"। अब मान लें कि हम एक कन्स्ट्रक्टर बनाना चाहते हैं जो एक मूल्य लेता है। आप यह कर सकते हैं:

public class Example { 
    ... 
    public Example (int value) { 
     this.value = value; 
    } 
    ... 
} 

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

public class Example { 
    ... 
    public Example (int value) throws IllegalArgumentException { 
     setValue(value); // throws if out of range 
    } 
    ... 
} 

तो वहाँ यह करने के लिए कई लाभ हैं।

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

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

हालांकि, सभी में, आमतौर पर हर जगह सेटर्स का उपयोग करना एक अच्छा विचार है, यह आम तौर पर क्लीनर और स्पष्ट कोड का कारण बनता है जो जटिलता बढ़ने के साथ बनाए रखना आसान होता है।

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

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

आप देखेंगे कि गेटटर/सेटर उपर्युक्त उदाहरण में अंतिम है। ऐसा इसलिए है क्योंकि हमारा नियम यह है कि "किसी भी उदाहरण के पास 0 से 10 का मान होना चाहिए"। इसलिए यह नियम उप-वर्गों तक फैलता है। अगर हमारे पास वह नियम नहीं था और यदि कोई उदाहरण किसी भी मूल्य पर ले सकता है, तो हमें अंतिम सेटटर की आवश्यकता नहीं होगी और उप-वर्गों को ओवरराइड करने की अनुमति दे सकती है।

उम्मीद है कि मदद करता है।

+0

ओवरराइड सेटर्स के अंत में टिप्पणी जोड़ा गया। –

0

अन्य वर्गों से encapsulation को प्रोत्साहित करने के लिए निजी रूप से चर सेट करना है।

जब तक setName(String) कुछ अतिरिक्त करने के लिए किया गया था (जो विधि का नाम नहीं दर्शाता है), जब आप उस वर्ग में हों, जहां निजी चर है, तो सेटटर का उपयोग करना अनावश्यक है।

+1

यह * पूरी तरह से सत्य नहीं है, क्योंकि आप अपने सभी सत्यापन तर्क को एक सेटर में समाहित कर सकते हैं और इस प्रकार अन्यत्र से सत्यापन सेवाएं प्राप्त कर सकते हैं आपकी कक्षा। –

+0

+1 यकीन है, सहमत हैं। – ataulm

0

यह कैप्सूलीकरण हार नहीं करता है के बाद से निजी सदस्य अभी भी अन्य वर्गों

से छिपा हुआ है संशोधक विधि किसी भी तर्क नहीं है, तो और बस सदस्य सेट तो सीधे कॉल के सदस्य निर्धारित करने के बीच कोई अंतर नहीं है इसकी सेटर विधि हालांकि बेहतर अभ्यास के लिए सेटटर को बुलाया जाना चाहिए।

सेटर इंगित करता है कि इस व्यक्ति का नाम भविष्य में बदल सकता है और इसे पूरी तरह से ऑब्जेक्ट ऑब्जेक्ट बनाने के बिना आसानी से अनुमति देता है।

2

कभी-कभी जब आप कक्षा को अपरिवर्तनीय बनाना चाहते हैं, तो यह केवल उन चीजों में से एक है जिन्हें आपको करने की आवश्यकता है। और उस मामले में बिल्कुल सेटर विधियां नहीं हैं।

+0

इसके बजाय निजी सेटर्स रखने के लिए सत्यापन के संबंध में एक तर्क है। लेकिन यह बहुत सच है, कभी-कभी आप केवल सरल कोड को एक साथ रखना चाहते हैं, और बहुत कम लाभ वाले निजी सेटर्स बनाने के लिए असुविधाजनक है। –

0

निजी चर वर्ग

settng निजी variabels में सीधे कहीं भी जाया जा सकता है उन्हें अन्य वर्गों

2

संदर्भ पर निर्भर से संपुटित करने के लिए है, getters और setters के उपयोग वास्तव में कैप्सूलीकरण का एक बड़ा उल्लंघन है रचनाकारों में सदस्य चर का उपयोग करने से। यदि आप इस वर्ग के सदस्य चर 'नाम' को सेट करना चाहते हैं, तो इनमें से कोई भी दृष्टिकोण काम करेगा क्योंकि निर्माण कॉलर से छिपा हुआ है और इस प्रकार encapsulation का उल्लंघन नहीं कर रहा है। एक चेतावनी यह है कि कन्स्ट्रक्टर के भीतर सेटनाम का उपयोग उप-वर्ग में एक ओवरराइड विधि को कॉल कर सकता है जो कि आप जो चाहते हैं वह नहीं हो सकता है (क्योंकि यह सुपरक्लास में अपरिभाषित नाम छोड़ सकता है)।

यहाँ मिलती-जुलती सवाल है कि अतिरिक्त अंतर्दृष्टि प्रदान कर सकता है:

calling setters from a constructor

0

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

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

+0

मुझे नहीं लगता कि यह सवाल का जवाब देता है (** या शायद मैंने गलत समझा **)। ओपी यह नहीं पूछ रहा है कि जब आप पहले से ही सेटर्स प्रदान कर चुके हैं तो कन्स्ट्रक्टर में चर शुरू करना उचित है; बल्कि, ओपी कन्स्ट्रक्टर के भीतर से कहा गया सेटर्स के _use_ के बारे में पूछ रहा है। – ataulm

0

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

+0

इसके बजाय निजी सेटर्स रखने के लिए सत्यापन के संबंध में एक तर्क है (वेरिएबल्स के लिए एसएसपी जो एकाधिक स्थानों में सेट हो सकते हैं)। लेकिन यह बहुत सच है, कभी-कभी आप केवल सरल कोड को एक साथ रखना चाहते हैं, और बहुत कम लाभ वाले निजी सेटर्स बनाने के लिए असुविधाजनक है। –

0

क्लास में मूल्यों को सीधे असाइन करना ठीक है, बशर्ते किटर कोई अन्य प्रसंस्करण नहीं करता है।

मूल रूप से setters/टिककर खेल ऐसे निजी वस्तु के संदर्भ के बजाय डेटा की प्रतिलिपि लौटने, गेटर आदि में डेटा मान्य के रूप में निजी डेटा तक प्रतिबंधात्मक पहुँच प्रदान करने के लिए उपयोग किया जाता ..

के बाद से निर्माता वस्तु का हिस्सा है खुद, और हम निश्चित हैं कि हम क्या कर रहे हैं सही है, तो ठीक है।

+0

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

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