गेटर्स और सेटर / एक्सेसर्स का उपयोग क्यों करें?


1540

गेटवे और सेटर्स का उपयोग करने का क्या फायदा है - जो केवल उन चर के लिए सार्वजनिक क्षेत्रों का उपयोग करने के बजाय प्राप्त और सेट करते हैं?

यदि गेटर्स और सेटर्स कभी भी सिंपल गेट / सेट से अधिक कर रहे हैं, तो मैं इसे बहुत जल्दी समझ सकता हूं, लेकिन मैं 100% स्पष्ट नहीं हूं कि कैसे:

public String foo;

से भी बदतर है:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

जबकि पूर्व बहुत कम बॉयलर कोड लेता है।


6
@Dean जम्मू: कई अन्य सवालों के साथ डुप्लिकेट: stackoverflow.com/search?q=getters+setters
असफ़

8
बेशक, दोनों समान रूप से खराब होते हैं जब ऑब्जेक्ट को बदलने के लिए संपत्ति की आवश्यकता नहीं होती है। मैं बल्कि सब कुछ निजी बनाना चाहता हूं, और यदि आवश्यक हो तो गेटर्स जोड़ें और यदि आवश्यक हो तो बसता है।
टोरेक


34
यदि आप कार्यात्मक कोड या अपरिवर्तनीय वस्तुएँ लिखते हैं, तो "एक्सेसर्स बुराई हैं"। यदि आप स्टेटफुल म्यूटेबल ऑब्जेक्ट लिखते हैं, तो वे बहुत आवश्यक हैं।
क्रिश्चियन हैटर

जवाबों:


980

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

यहाँ कुछ कारणों से मैं अवगत हूँ:

  • संपत्ति प्राप्त करने या स्थापित करने से जुड़े व्यवहार का एनकैप्सुलेशन - यह अतिरिक्त कार्यक्षमता (जैसे सत्यापन) को बाद में और अधिक आसानी से जोड़ने की अनुमति देता है।
  • वैकल्पिक प्रतिनिधित्व का उपयोग करके संपत्ति को उजागर करते समय संपत्ति के आंतरिक प्रतिनिधित्व को छिपाना।
  • परिवर्तन से अपने सार्वजनिक इंटरफ़ेस को इन्सुलेट करना - मौजूदा उपभोक्ताओं को प्रभावित किए बिना कार्यान्वयन को बदलने के लिए सार्वजनिक इंटरफ़ेस को स्थिर रहने की अनुमति देता है।
  • संपत्ति के जीवनकाल और स्मृति प्रबंधन (निपटान) शब्दार्थ को नियंत्रित करना - विशेष रूप से गैर-प्रबंधित मेमोरी वातावरण (जैसे सी ++ या ऑब्जेक्टिव-सी) में महत्वपूर्ण है।
  • डिबगिंग अवरोधन बिंदु प्रदान करने के लिए जब कोई संपत्ति रनटाइम में बदलती है - डिबगिंग कब और कहाँ एक विशेष मूल्य में बदल जाती है, कुछ भाषाओं में इसके बिना काफी मुश्किल हो सकता है।
  • पुस्तकालयों के साथ बेहतर अंतर्संचालनीयता जो संपत्ति पाने वाले / बसने वालों के खिलाफ काम करने के लिए डिज़ाइन की गई हैं - मॉकिंग, सीरियलाइज़ेशन, और डब्ल्यूपीएफ का ख्याल आता है।
  • संपत्ति / व्यवहारकर्ता के तरीकों को ओवरराइड करने से संपत्ति कैसे व्यवहार करती है और कैसे उजागर होती है, इसके शब्दार्थ को बदलने के लिए विरासत की अनुमति देना।
  • मान के बजाए लैम्ब्डा एक्सप्रेशन के रूप में गेटर / सेटर को पास करना।
  • गेटर्स और सेटर विभिन्न एक्सेस स्तरों की अनुमति दे सकते हैं - उदाहरण के लिए गेट सार्वजनिक हो सकता है, लेकिन सेट को संरक्षित किया जा सकता है।

59
+1। बस जोड़ने के लिए: आलसी लोडिंग की अनुमति देना। लेखन पर प्रतिलिपि की अनुमति।
न्यूबीजेड

6
@bjarkef: मेरा मानना ​​है कि एक्सेसर publicविधियाँ कोड दोहराव का कारण बनती हैं, और जानकारी को उजागर करती हैं। पब्लिक एक्सेसर्स मार्शलिंग (क्रमबद्धता) के लिए आवश्यक नहीं हैं। कुछ भाषाओं (जावा) में, publicएक्सेसर्स पर निर्भर वर्गों को तोड़े बगैर बदले प्रकार बदला नहीं जा सकता। इसके अलावा, मेरा मानना ​​है कि वे ओओ सिद्धांतों के लिए काउंटर चलाते हैं। इसे भी देखें: stackoverflow.com/a/1462424/59087
डेव जार्विस

15
@ एसएसबी: एक संपत्ति सेट्टर का उपयोग करके खरीदी गई एक चीज, यहां तक ​​कि एक अच्छी तरह से डिज़ाइन किए गए ढांचे में, एक संपत्ति बदलने पर किसी वस्तु को दूसरे को सूचित करने की क्षमता है।
सुपरकैट

22
@ सुपरकैट: हालांकि, मैं आम तौर पर सार्वजनिक डेटा को बढ़ावा नहीं दे रहा हूं। अन्य वस्तुओं की अधिसूचना सिर्फ वास्तविक तरीकों से ही की जा सकती है, जिसमें (कम या ज्यादा) सार्वजनिक डेटा फ़ील्ड के साथ डेटा कंटेनर पर एक महत्वपूर्ण अमूर्तता प्रदान की जाती है। इसके बजाय plane.turnTo(dir); plane.setSpeed(spd); plane.setTargetAltitude(alt); plane.getBreaks().release();मैं कहना चाहता हूं plane.takeOff(alt)। प्लेन को takingOffमोड में डालने के लिए कौन से आंतरिक डेटा फ़ील्ड को बदलने की आवश्यकता है, मेरी कोई चिंता नहीं है। और क्या अन्य वस्तुओं ( breaks) विधि सूचित करता है कि मैं या तो जानना नहीं चाहता।
sbi

8
@ बेनी: मैं वास्तव में नहीं जानता कि यह कैसे कहना है। "एक्सेसर्स" केवल "गेटर्स / सेटर" का एक पर्याय है, और मैंने अपनी पहली दो टिप्पणियों में बताया कि वे "ओओपी" शब्द का दुरुपयोग क्यों हैं। यदि आपको इसमें पहुंचने और सीधे राज्य में हेरफेर करने की आवश्यकता है, तो यह उस शब्द के ओओपी अर्थ में एक वस्तु नहीं है।
sbi

480

क्योंकि अब से 2 सप्ताह (महीने, वर्ष) जब आपको पता चलता है कि आपके सेटर को केवल मूल्य निर्धारित करने की तुलना में अधिक करने की आवश्यकता है , तो आपको यह भी महसूस होगा कि संपत्ति का उपयोग सीधे 238 अन्य वर्गों में किया गया है :-)


84
मैं 500k लाइन ऐप पर बैठा हूं और घूर रहा हूं जहां इसकी कभी जरूरत नहीं पड़ी। उस ने कहा, अगर यह एक बार की जरूरत है, यह एक रखरखाव दुःस्वप्न पैदा करना शुरू कर देगा। मेरे लिए एक चेकमार्क के लिए काफी अच्छा है।
डीन जे

20
मैं केवल आपको और आपके ऐप को ईर्ष्या कर सकता हूं :-) यह कहा, यह वास्तव में आपके सॉफ़्टवेयर स्टैक पर भी निर्भर करता है। डेल्फी, उदाहरण के लिए (और सी # - मुझे लगता है?) आपको प्रथम श्रेणी के नागरिकों के रूप में गुणों को परिभाषित करने की अनुमति देता है जहां वे शुरू में सीधे एक फ़ील्ड पढ़ / लिख सकते हैं लेकिन - क्या आपको इसकी आवश्यकता है - गेट्टर / सेटर विधियों के माध्यम से भी ऐसा करें। बहुत सुविधाजनक। जावा, अफसोस, जावबीन के मानक का उल्लेख नहीं करना - जो आपको गेटर्स / सेटर का उपयोग करने के लिए मजबूर करता है।
ChssPly76

14
हालांकि यह वास्तव में एक्सेसर्स का उपयोग करने का एक अच्छा कारण है, कई प्रोग्रामिंग वातावरण और संपादक अब रिफैक्टरिंग के लिए समर्थन प्रदान करते हैं (या तो आईडीई में या मुफ्त ऐड-इन्स के रूप में) जो कुछ हद तक समस्या के प्रभाव को कम करता है।
LBushkin

62
प्री-
मेच्योर

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

357

एक सार्वजनिक क्षेत्र एक गेट्टर / सेटर जोड़ी से भी बदतर नहीं है जो क्षेत्र को वापस करने और इसे असाइन करने के अलावा कुछ भी नहीं करता है। सबसे पहले, यह स्पष्ट है कि (अधिकांश भाषाओं में) कोई कार्यात्मक अंतर नहीं है। कोई भी अंतर अन्य कारकों में होना चाहिए, जैसे रखरखाव या पठनीयता।

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

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

यदि यह अनुबंध नहीं होना चाहिए था, तो इंटरफ़ेस क्लाइंट को अमान्य राज्यों में ऑब्जेक्ट डालने की अनुमति दे रहा था। यह एनकैप्सुलेशन के बिल्कुल विपरीत है यदि वह क्षेत्र वास्तव में शुरू से किसी भी चीज़ के लिए सेट नहीं किया जा सकता है, तो शुरू से ही सत्यापन क्यों नहीं था?

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

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

class Foo {
public:
    int DaysLeft;
    int ContestantNumber;
};

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

ग्राहक : "मैं इस वर्ग की वस्तु के साथ क्या कर सकता हूं?"
डिजाइनर : "आप कई चर पढ़ सकते हैं और लिख सकते हैं।"
ग्राहक : "ओह ... कूल, मुझे लगता है?"

गेटर्स और सेटर का उपयोग करने के कारण हैं, लेकिन यदि वे कारण मौजूद नहीं हैं, तो झूठे इनकैप्सुलेशन देवताओं के नाम पर गेट्टर / सेटर जोड़े बनाना अच्छी बात नहीं है। गेटर्स या सेटर बनाने के वैध कारणों में अक्सर उन चीज़ों को शामिल किया जाता है जो आपके द्वारा बाद में किए जा सकने वाले संभावित बदलावों जैसे सत्यापन या अलग-अलग आंतरिक अभ्यावेदन शामिल हैं। या हो सकता है कि मूल्य ग्राहकों द्वारा पठनीय होना चाहिए, लेकिन लिखने योग्य नहीं है (उदाहरण के लिए, एक शब्दकोश के आकार को पढ़ना), इसलिए एक साधारण गेट्टर एक अच्छा विकल्प है। लेकिन उन कारणों को वहाँ होना चाहिए जब आप चुनाव करते हैं, और न केवल एक संभावित चीज के रूप में आप बाद में चाहते हैं। यह YAGNI ( You Ain’t Gonna Need It ) का एक उदाहरण है ।


12
शानदार जवाब (+1)। मेरी एकमात्र आलोचना यह है कि मुझे यह पता लगाने के लिए कई बार पढ़ा कि अंतिम पैराग्राफ में "सत्यापन" पहले कुछ में "सत्यापन" से अलग कैसे हुआ (जिसे आपने बाद के मामले में फेंक दिया था लेकिन पूर्व में पदोन्नत किया गया था); शब्दों को समायोजित करने से उस संबंध में मदद मिल सकती है।
ऑर्बिट

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

2
एक प्रमुख अवलोकन यह है कि गेटर्स बसने वालों की तुलना में बहुत अधिक उपयोगी हैं। एक गेटर एक गणना मूल्य, या एक कैश्ड गणना मूल्य वापस कर सकता है। सभी सेटर कुछ सत्यापन कर सकते हैं और privateक्षेत्र को बदल सकते हैं । यदि किसी वर्ग का कोई बसाव नहीं है, तो उसे अपरिवर्तनीय बनाना आसान है।
राएडवल्ड

7
ईआर, मुझे लगता है कि आप नहीं जानते कि एक वर्ग अपरिवर्तनीय क्या है। यदि यह एक गैर-तुच्छ संरचना है, तो इसका बहुत मतलब है कि इसमें आक्रमण करने वाले व्यक्ति हैं और कोई भी इसे ध्यान में रखे बिना इसे डिजाइन नहीं कर सकता है। "बग था, एक सदस्य को गलत अपडेट किया गया था।" बहुत ज्यादा पढ़ता है जैसे "एक सदस्य अद्यतन ने वर्ग के आक्रमणकारियों का उल्लंघन किया"। एक अच्छी तरह से डिज़ाइन किया गया वर्ग क्लाइंट कोड को अपने आक्रमणकारियों का उल्लंघन करने की अनुमति नहीं देता है।
आर। मार्टिनो फर्नांडिस

5
+1 के लिए 'गूंगा डेटा धारकों को गूंगा डेटा धारकों की तरह दिखना चाहिए' दुर्भाग्य से, हर कोई इन दिनों सब कुछ गूंगा डेटा धारकों के आसपास डिजाइन करने के लिए लगता है, और बहुत सारे ढांचे को भी इसकी आवश्यकता होती है ...
जोएरी हेंड्रिकक्स

92

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

कहो कि आप कोड की सैकड़ों लाइनें देख रहे हैं और आप इस पर आते हैं:

person.name = "Joe";

यह एक खूबसूरती से बस कोड का टुकड़ा है जब तक आप एक सेटर का एहसास नहीं करते हैं। अब, आप उस सेटर का अनुसरण करते हैं और पाते हैं कि वह व्यक्ति को सेट करता है। जहाँ आपकी मेमोरी लीक हो रही थी।

पहली नज़र में कोड के एक स्थानीय टुकड़े को समझना अच्छी पठनीयता का एक महत्वपूर्ण गुण है जिसे पाने वाले और बसने वाले टूट जाते हैं। यही कारण है कि मैं जब मैं कर सकता हूं तो उनसे बचने की कोशिश करता हूं, और जब मैं उनका उपयोग करता हूं तो वे कम से कम करते हैं।


8
हाँ। वर्तमान में एक बड़े कोडबेस को फिर से बनाना, और यह एक बुरा सपना रहा है। गेटर्स और सेटर बहुत ज्यादा रास्ता बनाते हैं, जिसमें अन्य बहुत व्यस्त गेटर्स को कॉल करना और बसने के लिए कुछ भी करने के लिए पठनीयता को कम करना शामिल है। एक्सेसर्स का उपयोग करने के लिए मान्यता एक बहुत बड़ा कारण है, लेकिन इनका उपयोग किसी भी संभावित लाभ को हटाने के लिए लगता है।
फादेकोमिक

31
यह वाक्यात्मक चीनी के खिलाफ तर्क है, सामान्य रूप से बसने के खिलाफ नहीं।
फिल

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

"यह एक खूबसूरती से बस कोड का टुकड़ा है जब तक आपको इसके सेटर का एहसास नहीं होता" - हे, क्या जावा के बारे में या सी # के बारे में मूल पोस्ट थी? :)
होन्ज़ा ज़िदेक

मैं पठनीयता के संबंध में पूरी तरह सहमत हूं। यह पूरी तरह से स्पष्ट है कि कब क्या हो रहा person.name = "Joe";है। जानकारी के तरीके में कोई कमी नहीं है, सिंटैक्स हाइलाइटिंग से पता चलता है कि यह एक क्षेत्र है और रीफैक्टरिंग सरल है (दो तरीकों और एक क्षेत्र को रिफैक्ट करने की आवश्यकता नहीं है)। दूसरा, उन सभी व्यर्थ मस्तिष्क चक्रों के बारे में सोचकर "getIsValid ()" या ऐसा होना चाहिए "VValid ()" आदि को भुलाया जा सकता है। मैं उस समय के बारे में सोच भी नहीं सकता, जब मुझे एक गेट्टर / सेटर द्वारा बग से बचाया गया हो।
विल

53

एक शुद्ध वस्तु उन्मुख दुनिया में गेटर्स और सेटर एक भयानक विरोधी पैटर्न है । इस लेख को पढ़ें: गेटर्स / सेटर्स। बुराई। काल । संक्षेप में, वे प्रोग्रामर को डेटा संरचनाओं के रूप में वस्तुओं के बारे में सोचने के लिए प्रोत्साहित करते हैं, और इस प्रकार की सोच शुद्ध प्रक्रियात्मक होती है (जैसे कि COBOL या C)। ऑब्जेक्ट-ओरिएंटेड भाषा में डेटा संरचनाएं नहीं होती हैं, लेकिन केवल ऑब्जेक्ट जो व्यवहार को उजागर करते हैं (विशेषता / गुण नहीं!)।

आपको एलिगेंट ऑब्जेक्ट्स की धारा 3.5 (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के बारे में मेरी किताब) में उनके बारे में अधिक जानकारी मिल सकती है ।


7
गेटिक और सेटर एनीमिक डोमेन मॉडल का सुझाव देते हैं।
राएडवल्ड

7
दिलचस्प दृश्य। लेकिन अधिकांश प्रोग्रामिंग संदर्भों में हमें डेटा संरचनाओं की आवश्यकता होती है। जुड़ा हुआ लेख "डॉग" उदाहरण ले रहा है। हाँ, आप एक विशेषता सेट करके वास्तविक दुनिया के कुत्ते का वजन नहीं बदल सकते ... लेकिन new Dog()यह कुत्ता नहीं है। यह एक वस्तु है जो एक कुत्ते के बारे में जानकारी रखती है। और उस उपयोग के लिए, गलत तरीके से दर्ज वजन को सही करने में सक्षम होना स्वाभाविक है।
स्टीफन सी।

3
खैर, मैंने इसे आपके सामने रखा है कि अधिकांश उपयोगी कार्यक्रमों को वास्तविक दुनिया की वस्तुओं को मॉडल / अनुकरण करने की आवश्यकता नहीं है। IMO, यह वास्तव में प्रोग्रामिंग भाषाओं के बारे में बिल्कुल नहीं है। यह इस बारे में है कि हम किन कार्यक्रमों के लिए लिखते हैं।
स्टीफन सी।

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

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

52

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

public void setSpeed(int speed) {
  if ( speed > 100 ) {
    this.speed = 100;
  } else {
    this.speed = speed;
  }
}

अब क्या होगा अगर आपके कोड में हर कोई आप सार्वजनिक क्षेत्र का उपयोग कर रहा था और तब आपको महसूस हुआ कि आपको उपरोक्त आवश्यकता की आवश्यकता है? केवल अपने सेटर को संशोधित करने के बजाय सार्वजनिक क्षेत्र के हर उपयोग का मज़ा लें।

मेरे 2 सेंट :)


61
सार्वजनिक क्षेत्र के हर उपयोग का शिकार करना उतना कठिन नहीं होना चाहिए। इसे निजी बनाएं और संकलक को खोजने दें।
नाथन फेलमैन

12
यह निश्चित रूप से सच है, लेकिन क्यों इसे बनाने के लिए डिज़ाइन किया गया था की तुलना में किसी भी कठिन बनाते हैं। गेट / सेट दृष्टिकोण अभी भी बेहतर उत्तर है।
०५ पर हार्ड्रिज

28
@ नथन: अन्य उपयोगों को खोजना समस्या नहीं है। उन सभी को बदलना है
ग्रीम पेरो

22
@GraemePerrow उन सभी को बदलने के लिए एक फायदा है, एक समस्या नहीं है :( क्या होगा यदि आपके पास कोड था जो मान लिया गया कि गति 100 से अधिक हो सकती है (क्योंकि, आप जानते हैं, इससे पहले कि आप अनुबंध को तोड़ दें, यह!) ( while(speed < 200) { do_something(); accelerate(); })
आर। मार्टिनहो फर्नांडिस

29
यह बहुत बुरा उदाहरण है! किसी को फोन करना चाहिए: myCar.setSpeed(157);और कुछ पंक्तियों के बाद speed = myCar.getSpeed();और अब ... मैं चाहता हूं कि आप speed==100यह समझने की कोशिश करते हुए खुश डिबगिंग करें कि यह कब होना चाहिए157
पिओटर अलेक्जेंडर च्मिलोव्स्की

38

एक्सेसर्स और म्यूटेटर्स का एक फायदा यह है कि आप सत्यापन कर सकते हैं।

उदाहरण के लिए, यदि fooसार्वजनिक था , तो मैं इसे आसानी से सेट कर सकता था nullऔर फिर कोई दूसरा व्यक्ति ऑब्जेक्ट पर कॉल करने का प्रयास कर सकता था। लेकिन यह अब वहाँ नहीं है! एक setFooविधि के साथ , मैं यह सुनिश्चित कर सकता fooथा कि कभी भी सेट नहीं किया गया था null

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


28

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

class Simple(object):
   def _get_value(self):
       return self._value -1

   def _set_value(self, new_value):
       self._value = new_value + 1

   def _del_value(self):
       self.old_values.append(self._value)
       del self._value

   value = property(_get_value, _set_value, _del_value)

2
हां, मैंने अपने उत्तर के नीचे एक टिप्पणी में कहा है। जावा गेटर्स / सेटर्स को एक बैसाखी के रूप में उपयोग करने वाली एकमात्र भाषा नहीं है, जैसे कि पायथन केवल गुणों को परिभाषित करने में सक्षम भाषा नहीं है। मुख्य बिंदु, हालांकि, अभी भी बनी हुई है - "संपत्ति" समान "सार्वजनिक क्षेत्र" नहीं है।
ChssPly76

1
@jcd - बिल्कुल नहीं। आप अपने "इंटरफ़ेस" को परिभाषित कर रहे हैं (अपने सार्वजनिक क्षेत्रों को उजागर करके सार्वजनिक एपीआई यहां एक बेहतर शब्द होगा)। एक बार जो किया है, वहाँ वापस नहीं जा रहा है। गुण फ़ील्ड नहीं हैं, क्योंकि वे आपको फ़ील्ड तक पहुँचने के प्रयासों को रोकने के लिए एक तंत्र प्रदान करते हैं (यदि उन्हें परिभाषित किया गया है तो उन्हें तरीकों पर ले जाकर); हालाँकि, गटर / सेटर के तरीकों पर सिंटैक्स चीनी से अधिक कुछ नहीं है। यह बहुत सुविधाजनक है, लेकिन यह अंतर्निहित प्रतिमान को परिवर्तित नहीं करता है - उन तक पहुंच पर कोई नियंत्रण नहीं रखने वाले क्षेत्रों को उजागर करना इनकैप्सुलेशन के सिद्धांत का उल्लंघन करता है।
ChssPly76

14
@ ChssPly76- मैं असहमत हूं। मेरे पास बस उतना ही नियंत्रण है जैसे कि वे गुण थे, क्योंकि जब भी मुझे जरूरत होती है, मैं उन्हें गुण बना सकता हूं। बॉयलरप्लेट गेटर्स और सेटर का उपयोग करने वाली एक संपत्ति और कच्चे विशेषता के बीच कोई अंतर नहीं है, सिवाय इसके कि कच्चा विशेषता तेज है, क्योंकि यह कॉलिंग विधियों के बजाय अंतर्निहित भाषा का उपयोग करता है। कार्यात्मक रूप से, वे समान हैं। एकमात्र तरीका है कि उल्लंघन का उल्लंघन किया जा सकता है यदि आपको लगता है कि कोष्ठक ( obj.set_attr('foo')) स्वाभाविक रूप से संकेतों ( obj.attr = 'foo') के बराबर बेहतर हैं । सार्वजनिक पहुंच सार्वजनिक पहुंच है।
jcdyer

1
@ जयदीप जितना नियंत्रण पर हाँ, लेकिन उतनी पठनीयता नहीं, अन्य लोग अक्सर गलत मानते हैं कि obj.attr = 'foo'बस चर को बिना किसी और चीज़ के सेट किया जाता है
टिमो हुओवेनन

9
@TimoHuovinen जावा में उपयोगकर्ता की तुलना में कोई भी भिन्न यह कैसे मान सकता है कि obj.setAttr('foo')"बस चर को बिना किसी और चीज़ के सेट किया गया है"? अगर यह एक सार्वजनिक तरीका है, तो यह एक सार्वजनिक तरीका है। यदि आप इसका उपयोग कुछ साइड-इफ़ेक्ट को प्राप्त करने के लिए करते हैं, और यह सार्वजनिक है, तो आप बेहतर तरीके से काम करने वाली हर चीज़ पर भरोसा कर सकते हैं, जैसे कि केवल वही साइड इफेक्ट हुआ हो ( अन्य सभी कार्यान्वयन विवरण और अन्य साइड इफेक्ट्स के साथ, संसाधन उपयोग, जो भी हो , उपयोगकर्ता की चिंताओं से छिपा हुआ है)। यह पायथन के साथ बिल्कुल अलग नहीं है। प्रभाव को प्राप्त करने के लिए पायथन का सिंटैक्स सिर्फ सरल है।
ely

25

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


24

धन्यवाद, जिसने वास्तव में मेरी सोच को स्पष्ट किया। अब यहाँ (लगभग) 10 (लगभग) अच्छे कारण गेटर्स और सेटर का उपयोग नहीं करना है:

  1. जब आपको पता चलता है कि आपको बस सेट से अधिक करने और मूल्य प्राप्त करने की आवश्यकता है, तो आप केवल फ़ील्ड को निजी बना सकते हैं, जो आपको तुरंत बताएगा कि आपने इसे सीधे कहां एक्सेस किया है।
  2. आपके द्वारा किया गया कोई भी सत्यापन केवल संदर्भ मुक्त हो सकता है, जो सत्यापन शायद ही कभी व्यवहार में हो।
  3. आप सेट किए जा रहे मान को बदल सकते हैं - यह एक पूर्ण दुःस्वप्न है जब कॉलर आपको एक मूल्य देता है कि वे [शॉक हॉरर] चाहते हैं कि आप आईएस के रूप में स्टोर करें।
  4. आप आंतरिक प्रतिनिधित्व को छिपा सकते हैं - शानदार, इसलिए आप सुनिश्चित कर रहे हैं कि ये सभी ऑपरेशन सममित रूप से सही हैं?
  5. आपने अपने सार्वजनिक इंटरफ़ेस को चादरों के नीचे बदलाव से अछूता रखा है - यदि आप एक इंटरफ़ेस डिज़ाइन कर रहे थे और यह सुनिश्चित नहीं कर रहे थे कि किसी चीज़ की सीधी पहुँच ठीक है, तो आपको डिज़ाइन करना चाहिए।
  6. कुछ पुस्तकालयों से यह उम्मीद है, लेकिन कई नहीं - प्रतिबिंब, क्रमांकन, नकली वस्तुएं सभी सार्वजनिक क्षेत्रों के साथ ठीक काम करती हैं।
  7. इस वर्ग को सम्मिलित करते हुए, आप डिफ़ॉल्ट कार्यक्षमता को ओवरराइड कर सकते हैं - दूसरे शब्दों में आप कॉल करने वालों को न केवल कार्यान्वयन को छिपा सकते हैं बल्कि इसे असंगत बना सकते हैं।

पिछले तीन मैं बस छोड़ रहा हूँ (एन / ए या डी / सी) ...


11
मुझे लगता है कि महत्वपूर्ण तर्क यह है कि, "यदि आप एक इंटरफ़ेस डिज़ाइन कर रहे थे और यह सुनिश्चित नहीं कर रहे थे कि किसी चीज़ की सीधी पहुँच ठीक है या नहीं, तो आपको डिज़ाइन करना चाहिए।" गेटर्स / सेटर के साथ यह सबसे महत्वपूर्ण समस्या है: वे सार्वजनिक क्षेत्रों के (कम या ज्यादा) के एक वर्ग को कम करते हैं। में वास्तविक OOP, तथापि, एक वस्तु डेटा क्षेत्रों के एक कंटेनर से अधिक है। यह राज्य और एल्गोरिदम को उस राज्य में हेरफेर करने के लिए एन्क्रिप्ट करता है। इस कथन के बारे में यह महत्वपूर्ण है कि राज्य को समझाया जाना चाहिए और केवल वस्तु द्वारा प्रदान किए गए एल्गोरिदम द्वारा हेरफेर किया जाना चाहिए।
sbi

22

मुझे पता है कि थोड़ी देर हो गई है, लेकिन मुझे लगता है कि कुछ लोग हैं जो प्रदर्शन में रुचि रखते हैं।

मैंने थोड़ा प्रदर्शन परीक्षण किया है। मैंने एक क्लास "नंबरहॉल्डर" लिखा था, जो कि अच्छी तरह से एक इंटेगर है। आप या तो पढ़ने वाले की विधि का उपयोग करके anInstance.getNumber()या सीधे नंबर का उपयोग करके पूर्णांक तक पढ़ सकते हैं anInstance.number। मेरा प्रोग्राम दोनों तरीकों से संख्या 1,000,000,000 बार पढ़ता है। उस प्रक्रिया को पांच बार दोहराया जाता है और समय मुद्रित किया जाता है। मुझे निम्नलिखित परिणाम मिला है:

Time 1: 953ms, Time 2: 741ms
Time 1: 655ms, Time 2: 743ms
Time 1: 656ms, Time 2: 634ms
Time 1: 637ms, Time 2: 629ms
Time 1: 633ms, Time 2: 625ms

(समय 1 सीधा रास्ता है, समय 2 पाने वाला है)

आप देखिए, गेटटर हमेशा (लगभग) थोड़ा तेज होता है। फिर मैंने विभिन्न चक्रों के साथ प्रयास किया। 1 मिलियन के बजाय, मैंने 10 मिलियन और 0.1 मिलियन का उपयोग किया। परिणाम:

10 मिलियन चक्र:

Time 1: 6382ms, Time 2: 6351ms
Time 1: 6363ms, Time 2: 6351ms
Time 1: 6350ms, Time 2: 6363ms
Time 1: 6353ms, Time 2: 6357ms
Time 1: 6348ms, Time 2: 6354ms

10 मिलियन चक्रों के साथ, समय लगभग समान है। यहां 100 हजार (0.1 मिलियन) चक्र हैं:

Time 1: 77ms, Time 2: 73ms
Time 1: 94ms, Time 2: 65ms
Time 1: 67ms, Time 2: 63ms
Time 1: 65ms, Time 2: 65ms
Time 1: 66ms, Time 2: 63ms

अलग-अलग मात्रा में चक्रों के साथ, गेटटर नियमित तरीके से थोड़ा तेज होता है। मैं आशा करता हूं कि इससे आपको मदद मिली होगी।


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

16

जब तक आपकी वर्तमान डिलीवरी के लिए आवश्यक नहीं हो, तब तक गेटर्स का उपयोग न करें I भविष्य में क्या होगा, इस बारे में बहुत अधिक न सोचें, यदि किसी भी चीज को अधिकांश उत्पादन अनुप्रयोगों, प्रणालियों में परिवर्तन के अनुरोध को बदल दिया जाए।

सरल, आसान सोचें, आवश्यकता होने पर जटिलता जोड़ें।

मैं गहरी तकनीकी के व्यापार मालिकों की अज्ञानता का फायदा नहीं उठाऊंगा, सिर्फ इसलिए कि मुझे लगता है कि यह सही है या मुझे दृष्टिकोण पसंद है।

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


16

हम गेटर्स और सेटर का उपयोग करते हैं:

  • पुन: प्रयोज्यता के लिए
  • प्रोग्रामिंग के बाद के चरणों में सत्यापन करने के लिए

निजी वर्ग के सदस्यों तक पहुँचने के लिए गेट्टर और सेटर विधियाँ सार्वजनिक इंटरफेस हैं।


मंत्र का जाप

इनकैप्सुलेशन मंत्र खेतों को निजी और विधियों को सार्वजनिक बनाना है।

गेट्टर मेथड्स: हम निजी चर तक पहुँच प्राप्त कर सकते हैं।

सेटर विधियाँ: हम निजी क्षेत्रों को संशोधित कर सकते हैं।

भले ही गेट्टर और सेटर के तरीकों में नई कार्यक्षमता न हो, लेकिन हम उस तरीके को बनाने के लिए अपने दिमाग को बाद में बदल सकते हैं

  • बेहतर;
  • सुरक्षित; तथा
  • और तेज।

कहीं भी एक मूल्य का उपयोग किया जा सकता है, एक विधि जो उस मूल्य को वापस करती है उसे जोड़ा जा सकता है। के बजाय:

int x = 1000 - 500

उपयोग

int x = 1000 - class_name.getValue();

आम आदमी की शर्तों में

"व्यक्ति" वर्ग का प्रतिनिधित्व

मान लीजिए हमें इसका विवरण संग्रहीत करने की आवश्यकता है Person। इसके Personपास खेत हैं name, ageऔर sex। ऐसा करने के लिए तरीके बनाना शामिल है name, ageऔर sex। अब अगर हम किसी अन्य व्यक्ति की जरूरत बनाने के लिए, यह करने के लिए तरीके बनाने के लिए आवश्यक हो जाता है name, age, sexफिर से।

ऐसा करने के बजाय, हम class(Person)गटर और सेटर विधियों के साथ बीन बना सकते हैं । इसलिए कल class(Person class)जब भी हमें एक नए व्यक्ति को जोड़ने की जरूरत है (आंकड़ा देखें) जब भी हम इस बीन की वस्तुएं बना सकते हैं। इस प्रकार हम बीन क्लास के खेतों और तरीकों का पुन: उपयोग कर रहे हैं, जो कि बेहतर है।


15

मैंने जावा केस के लिए यह सोचते हुए काफी समय बिताया, और मुझे विश्वास है कि वास्तविक कारण हैं:

  1. इंटरफ़ेस पर कोड, कार्यान्वयन नहीं
  2. इंटरफेस केवल तरीके निर्दिष्ट करते हैं, फ़ील्ड नहीं

दूसरे शब्दों में, इंटरफ़ेस में फ़ील्ड निर्दिष्ट करने का एकमात्र तरीका एक नया मान लिखने के लिए एक विधि और वर्तमान मान पढ़ने के लिए एक विधि प्रदान करके है।

वो तरीके हैं कुख्यात गटर और सेटर…।


1
ठीक है, दूसरा प्रश्न; मामले में जहां यह एक परियोजना है जहां आप किसी को स्रोत निर्यात नहीं कर रहे हैं, और आपके पास स्रोत का पूरा नियंत्रण है ... क्या आप गेटर्स और सेटर के साथ कुछ भी हासिल कर रहे हैं?
डीन जे

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

15

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

मेरे पास एक प्रोजेक्ट में एक बेस पेज क्लास था जो मुझे सौंप दिया गया था जो कि कुछ डेटा को कुछ अलग वेब सर्विस कॉल से लोड कर रहा था, लेकिन उन वेब सर्विस कॉल में डेटा हमेशा सभी चाइल्ड पेज में उपयोग नहीं किया जाता था। सभी लाभों के लिए वेब सेवाएँ, "धीमी" की नई परिभाषाएँ, इसलिए यदि आप नहीं चाहते हैं, तो आप वेब सेवा कॉल नहीं करना चाहते हैं।

मैं सार्वजनिक क्षेत्रों से गेटर्स में चला गया, और अब गेटर्स कैश की जांच करते हैं, और अगर यह वेब सेवा नहीं है। इसलिए थोड़ी रैपिंग के साथ, बहुत सारी वेब सेवा कॉल को रोका गया।

इसलिए गेट्टर मुझे प्रत्येक चाइल्ड पेज पर यह पता लगाने की कोशिश करने से रोकता है कि मुझे क्या चाहिए। अगर मुझे इसकी आवश्यकता होती है, तो मैं गेट्टर को कॉल करता हूं, और यह मेरे लिए इसे खोजने के लिए जाता है अगर मेरे पास पहले से नहीं है।

    protected YourType _yourName = null;
    public YourType YourName{
      get
      {
        if (_yourName == null)
        {
          _yourName = new YourType();
          return _yourName;
        }
      }
    }

तो क्या गेटटर सेटर को बुलाता है?
icc97

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


13

अब तक के जवाबों में एक पहलू जो मुझे याद आया, वह है एक्सेस स्पेसिफिकेशन:

  • सदस्यों के लिए आपके पास सेटिंग और प्राप्त दोनों के लिए केवल एक एक्सेस विनिर्देश है
  • बसने और पाने वालों के लिए आप इसे ठीक से ट्यून कर सकते हैं और इसे अलग से परिभाषित कर सकते हैं

13

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

दो मुख्य हैं बहुरूपता, और मान्यता। भले ही यह एक बेवकूफ डेटा संरचना है।

मान लीजिए कि हमारे पास यह सरल वर्ग है:

public class Bottle {
  public int amountOfWaterMl;
  public int capacityMl;
}

एक बहुत ही सरल वर्ग जो धारण करता है कि उसमें कितना तरल है, और इसकी क्षमता क्या है (मिलीलीटर में)।

जब मैं करता हूं तो क्या होता है:

Bottle bot = new Bottle();
bot.amountOfWaterMl = 1500;
bot.capacityMl = 1000;

ठीक है, आप उम्मीद नहीं करेंगे कि काम करने के लिए, है ना? आप चाहते हैं कि किसी प्रकार की पवित्रता की जाँच हो। और इससे भी बदतर, अगर मैंने अधिकतम क्षमता कभी नहीं निर्दिष्ट की तो क्या होगा? ओह प्रिय, हमें एक समस्या है।

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

हम कुछ इस तरह से समाप्त करेंगे:

public interface LiquidContainer {
  public int getAmountMl();
  public void setAmountMl(int amountMl);
  public int getCapacityMl();
}

महान! और अब हम सिर्फ बोतल को इसमें बदलते हैं:

public class Bottle extends LiquidContainer {
  private int capacityMl;
  private int amountFilledMl;

  public Bottle(int capacityMl, int amountFilledMl) {
    this.capacityMl = capacityMl;
    this.amountFilledMl = amountFilledMl;
    checkNotOverFlow();
  }

  public int getAmountMl() {
    return amountFilledMl;
  }

  public void setAmountMl(int amountMl) {
     this.amountFilled = amountMl;
     checkNotOverFlow();
  }
  public int getCapacityMl() {
    return capacityMl;
  }

  private void checkNotOverFlow() {
    if(amountOfWaterMl > capacityMl) {
      throw new BottleOverflowException();
    }
}

मैं एक अभ्यास के रूप में बॉटलऑवरफ्लो एक्ससेप्शन की परिभाषा को एक पाठक के पास छोड़ दूँगा।

अब ध्यान दें कि यह कितना मजबूत है। अब हम अपने कोड में किसी भी प्रकार के कंटेनर के साथ बोतल के बजाय लिक्विडकोर्नर को स्वीकार कर सकते हैं। और ये बोतलें इस तरह के सामान से कैसे निपट सकती हैं, यह सब अलग-अलग हो सकता है। आपके पास ऐसी बोतलें हो सकती हैं जो बदलने पर उनके राज्य को डिस्क पर लिखती हैं, या जो बोतलें SQL डेटाबेस या GNU पर सहेजती हैं, उन्हें पता है कि और क्या है।

और इन सभी के पास विभिन्न व्हाट्सएप को संभालने के लिए अलग-अलग तरीके हो सकते हैं। बोतल सिर्फ जांच करती है और अगर यह बह निकला है तो यह एक RuntimeException फेंकता है। लेकिन यह गलत काम हो सकता है। (त्रुटि से निपटने के बारे में एक उपयोगी चर्चा होनी है, लेकिन मैं इसे उद्देश्य पर बहुत सरल रख रहा हूं। टिप्पणियों में लोग इस सरल दृष्टिकोण की खामियों को इंगित करेंगे;)।

और हाँ, ऐसा लगता है कि हम एक बहुत ही सरल विचार से बहुत बेहतर उत्तर प्राप्त कर रहे हैं।

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

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


2
मेरे द्वारा पढ़े गए इंटरफेस के पहले आधे-सभ्य विवरण के लिए धन्यवाद, "रिमोट कंट्रोल" या "कार" के लिए कोई संदर्भ देता है
djvs

1
"आपके पास बोतलें हो सकती हैं जब लेखक अपने राज्य को डिस्क में बदल देता है, या बोतलें जो SQL डेटाबेस पर बचाती हैं" मैंने इतनी मेहनत से एक्सडी को खो दिया। लेकिन वैसे भी, इसे पेश करने के लिए अच्छा विचार है!
ज़ेरुस

10

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

उन भाषाओं में जो "वास्तविक" गुणों का समर्थन करती हैं (पायथन, रूबी, शायद स्मॉलटाक?) तरीकों को प्राप्त करने / सेट करने का कोई मतलब नहीं है।


1
पुन: सी #। यदि आप किसी ऐसे कार्य के लिए कार्यक्षमता जोड़ते हैं / जो किसी भी तरह से पुन: उपयोग की आवश्यकता नहीं है?
स्टीमर 25

@ स्टीमर 25: क्षमा करें, गलत टाइप किया हुआ। मेरा मतलब था कि वर्ग के ग्राहकों को नए सिरे से तैयार करना होगा।
जॉन मिलिकिन

5
एक सेट विधि के लिए सत्यापन तर्क जोड़ने के लिए भाषा स्तर पर एक वर्ग के इंटरफ़ेस को बदलने की आवश्यकता नहीं होगी , लेकिन यह वास्तविक इंटरफ़ेस , उर्फ ​​अनुबंध को बदल देता है , क्योंकि यह पूर्व शर्त बदल देता है। कोई क्यों चाहता है कि संकलक ऐसा न करें कि जब यह एक ब्रेकिंग परिवर्तन के रूप में हो ?
आर। मार्टिनो फर्नांडिस

@ R.MartinhoFernandes इस "टूटी" समस्या को कैसे ठीक करता है? संकलक बता नहीं सकता है कि यह टूट रहा है या नहीं। यह केवल एक चिंता है जब आप दूसरों के लिए पुस्तकालय लिख रहे हैं, लेकिन आप इसे सार्वभौमिक zOMG के रूप में बना रहे हैं यहां ड्रेगन हो सकता है!
फिल

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

6

OO डिजाइन के मूल प्रिंसिपलों में से एक: एनकैप्सुलेशन!

यह आपको कई लाभ प्रदान करता है, जिनमें से एक यह है कि आप पर्दे के पीछे गेट्टर / सेटर के कार्यान्वयन को बदल सकते हैं लेकिन जब तक डेटा प्रकार समान रहेगा तब तक उस मूल्य का कोई भी उपभोक्ता काम करना जारी रखेगा।


23
इनकैप्सुलेशन गेटर्स और सेटरर्स ऑफर बहुत कम पतले हैं। देखें यहाँ
एसबी

यदि आपका सार्वजनिक इंटरफ़ेस बताता है कि 'फू' टाइप 'टी' का है और इसे किसी भी चीज़ पर सेट किया जा सकता है, तो आप इसे कभी नहीं बदल सकते। आप बाद में इसे 'Y' बनाने का निर्णय नहीं ले सकते हैं, और न ही आप आकार की कमी जैसे नियम लागू कर सकते हैं। इस प्रकार यदि आपके पास सार्वजनिक / सेट है जो बहुत अधिक सेट / प्राप्त नहीं करता है, तो आप कुछ भी हासिल नहीं कर रहे हैं जो एक सार्वजनिक क्षेत्र की पेशकश नहीं करेगा और इसका उपयोग करने के लिए अधिक बोझिल बना देगा। यदि आपके पास एक बाधा है, जैसे कि वस्तु को अशक्त करने के लिए सेट किया जा सकता है, या मान एक सीमा के भीतर होना चाहिए, तो हाँ, एक सार्वजनिक सेट विधि की आवश्यकता होगी, लेकिन आप अभी भी इस मान को सेट करने से एक अनुबंध प्रस्तुत कर सकते हैं जो ' t परिवर्तन
thecoshman

एक अनुबंध क्यों नहीं बदल सकता है?
फिल

5
यदि अनुबंध बदलते हैं तो चीजों को क्यों संकलित करना चाहिए?
आर। मार्टिनो फर्नांडिस

5

आपको गेटवे और सेटर का उपयोग तब करना चाहिए जब:

  • आप ऐसी किसी चीज़ से निपट रहे हैं जो वैचारिक रूप से एक विशेषता है, लेकिन:
    • आपकी भाषा में गुण नहीं हैं (या कुछ समान तंत्र, जैसे कि Tcl के चर निशान), या
    • आपकी भाषा का संपत्ति समर्थन इस उपयोग के मामले के लिए पर्याप्त नहीं है, या
    • आपकी भाषा के (या कभी-कभी आपके ढांचे के) मुहावरेदार सम्मेलन इस उपयोग के मामले के लिए गेटर्स या सेटर को प्रोत्साहित करते हैं।

तो यह बहुत ही कम सामान्य OO प्रश्न है; यह एक भाषा-विशिष्ट प्रश्न है, विभिन्न भाषाओं (और विभिन्न उपयोग मामलों) के लिए अलग-अलग उत्तरों के साथ।


एक OO सिद्धांत के दृष्टिकोण से, गेटर्स और सेटर बेकार हैं। आपकी कक्षा का इंटरफ़ेस वही है जो वह करता है, न कि उसकी स्थिति क्या है। (यदि नहीं, तो आपने गलत कक्षा लिखी है।) बहुत ही सरल मामलों में, जहां एक वर्ग क्या करता है, उदाहरण के लिए, आयताकार निर्देशांक में एक बिंदु का प्रतिनिधित्व करते हैं, * विशेषताएँ इंटरफ़ेस का हिस्सा हैं; गेटर्स और सेटलर्स बस क्लाउड। लेकिन कुछ भी लेकिन बहुत सरल मामलों में, न तो विशेषताएँ और न ही गेटर्स और सेटर इंटरफ़ेस का हिस्सा हैं।

दूसरा तरीका रखें: यदि आप मानते हैं कि आपके वर्ग के उपभोक्ताओं को यह भी पता नहीं होना चाहिए कि आपके पास एक spamविशेषता है, तो बहुत कम ही आप इसे विली-निली में बदल सकते हैं, तो उन्हें एक set_spamविधि देना वह आखिरी चीज है जिसे आप करना चाहते हैं।

* यहां तक ​​कि उस सरल वर्ग के लिए, आप जरूरी नहीं कि मूल्यों xऔर yमूल्यों को स्थापित करने की अनुमति देना चाहते हैं। यदि यह वास्तव में एक वर्ग है, ऐसा लगता है तरीकों नहीं होना चाहिए translate, rotateआदि? यदि यह केवल एक वर्ग है क्योंकि आपकी भाषा में रिकॉर्ड्स / स्ट्रक्चर्स / नामित ट्यूपल्स नहीं हैं, तो यह वास्तव में OO का प्रश्न नहीं है ...


लेकिन कोई भी सामान्य ओओ डिजाइन कभी नहीं कर रहा है। वे एक विशिष्ट भाषा में डिजाइन, और कार्यान्वयन कर रहे हैं। और कुछ भाषाओं में, गेटर्स और सेटर बेकार से दूर हैं।

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

यहां तक ​​कि अगर आपकी भाषा में गुण हैं, तो ऐसे मामले भी हो सकते हैं जहां वे अपर्याप्त या अनुचित हैं। उदाहरण के लिए, यदि आप डायनामिक एक्सेस के बिना भाषाओं में किसी विशेषता के शब्दार्थ को नियंत्रित करने के लिए उपवर्गों को अनुमति देना चाहते हैं, तो एक उपवर्ग एक गुण के लिए एक गणना की गई संपत्ति का स्थान नहीं ले सकता है।

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

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

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


4

ऑब्जेक्ट ओरिएंटेशन डिज़ाइन के दृष्टिकोण से, दोनों विकल्प कक्षाओं के इनकैप्सुलेशन को कमजोर करके कोड के रखरखाव के लिए हानिकारक हो सकते हैं। चर्चा के लिए आप इस उत्कृष्ट लेख को देख सकते हैं: http://typicalprogrammer.com/?p=23


3

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

गेट्टर और सेटर विधियों का उपयोग करने के कुछ फायदे हैं, जैसे कि आपको परिष्कृत कार्यक्षमता वाले सदस्यों को बनाने की क्षमता जो आप गुणों की तरह उपयोग कर सकते हैं। उन्होंने आपको केवल-पढ़ने और लिखने के लिए केवल गुण बनाने की सुविधा दी है।

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

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


3

कोड विकसित होता हैprivateजब आपको डेटा सदस्य सुरक्षा की आवश्यकता हो, तो यह बहुत अच्छा है । आखिरकार सभी वर्गों को "मिनीप्रोग्राम" की तरह होना चाहिए, जिसमें एक अच्छी तरह से परिभाषित इंटरफ़ेस है जिसे आप केवल आंतरिक के साथ पेंच नहीं कर सकते

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

int getVar() const { return var ; }

मतलब आपके पास है:

doSomething( obj->getVar() ) ;

के बजाय

doSomething( obj->var ) ;

न केवल getVar()नेत्रहीन शोर है, यह यह भ्रम देता है कि gettingVar()वास्तव में यह वास्तव में की तुलना में एक अधिक जटिल प्रक्रिया है। आप (वर्ग लेखक के रूप में) की पवित्रता के बारे varमें कैसे विशेष रूप से अपनी कक्षा के एक उपयोगकर्ता को भ्रमित कर रहे हैं यदि इसके पास एक पस्त्रात्रु सेटर है - तो ऐसा लगता है कि आप इन फाटकों को "सुरक्षित" करने के लिए डाल रहे हैं, जो आप जोर देते हैं, मूल्यवान है, (की पवित्रता var) लेकिन फिर भी आप यह मानते हैं कि varकिसी के लिए भी बस आने की क्षमता और set varजो कुछ भी मूल्य वे चाहते हैं, उसके बिना आप क्या कर रहे हैं, इस पर झाँकने की क्षमता से बहुत अधिक नहीं है ।

इसलिए मैं निम्नानुसार कार्यक्रम करता हूं ("चुस्त" प्रकार का दृष्टिकोण मानते हुए - अर्थात जब मैं कोड नहीं लिखता कि वास्तव में यह क्या कर रहा है / विस्तृत जलप्रपात शैली इंटरफ़ेस सेट की योजना बनाने के लिए समय या अनुभव नहीं है):

1) डेटा और व्यवहार के साथ बुनियादी वस्तुओं के लिए सभी सार्वजनिक सदस्यों के साथ शुरू करें। यही कारण है कि मेरे सभी C ++ "उदाहरण" कोड में आप मुझे हर जगह के structबजाय उपयोग करके देखेंगे class

2) जब किसी डेटा सदस्य के लिए किसी वस्तु का आंतरिक व्यवहार पर्याप्त जटिल हो जाता है, (उदाहरण के लिए, यह std::listकिसी प्रकार के ऑर्डर में आंतरिक रखना पसंद करता है ), तो एक्सेसर प्रकार के कार्य लिखे जाते हैं। क्योंकि मैं अपने आप से प्रोग्रामिंग कर रहा हूं, मैं हमेशा सदस्य को privateतुरंत सेट नहीं करता, लेकिन कहीं न कहीं सदस्य के विकास को " protectedया तो" बढ़ावा दिया जाएगा private

3) कक्षाएं जो पूरी तरह से समाप्त हो गई हैं और उनके इंटर्नल के बारे में सख्त नियम हैं (अर्थात वे जानते हैं कि वे क्या कर रहे हैं, और आप अपने इंटर्ल्स के साथ "बकवास" (तकनीकी शब्द) नहीं कर सकते हैं) classपदनाम, डिफ़ॉल्ट निजी सदस्य हैं, और केवल कुछ चुनिंदा सदस्यों को ही अनुमति दी जाती है public

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


1
"... एक अच्छी तरह से परिभाषित इंटरफ़ेस जिसे आप बस के आंतरिक के साथ पेंच नहीं कर सकते हैं" और बसने वालों में मान्यता।
आजी हैमरथिफ़िटी

3

एक्सेसर्स का उपयोग करने पर विचार करने का एक अच्छा कारण है कि कोई संपत्ति विरासत में नहीं है। अगला उदाहरण देखें:

public class TestPropertyOverride {
    public static class A {
        public int i = 0;

        public void add() {
            i++;
        }

        public int getI() {
            return i;
        }
    }

    public static class B extends A {
        public int i = 2;

        @Override
        public void add() {
            i = i + 2;
        }

        @Override
        public int getI() {
            return i;
        }
    }

    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.i);
        a.add();
        System.out.println(a.i);
        System.out.println(a.getI());
    }
}

आउटपुट:

0
0
4

3

गेट और सेटर का उपयोग ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के दो मूलभूत पहलुओं को लागू करने के लिए किया जाता है जो हैं:

  1. मतिहीनता
  2. encapsulation

मान लीजिए कि हमारे पास एक कर्मचारी वर्ग है:

package com.highmark.productConfig.types;

public class Employee {

    private String firstName;
    private String middleName;
    private String lastName;

    public String getFirstName() {
      return firstName;
    }
    public void setFirstName(String firstName) {
       this.firstName = firstName;
    }
    public String getMiddleName() {
        return middleName;
    }
    public void setMiddleName(String middleName) {
         this.middleName = middleName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFullName(){
        return this.getFirstName() + this.getMiddleName() +  this.getLastName();
    }
 }

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


1
मेरे पास बहुत सारे गेटर्स और सेटर हैं जो कुछ भी अनोखा नहीं है। getFullName एक अपवाद है क्योंकि यह कुछ और करता है। सिर्फ तीन चर सार्वजनिक होने के बाद getFullName रखने से प्रोग्राम को पढ़ने में आसानी होगी लेकिन फिर भी उस फुलनाम चीज़ को छिपाया जाएगा। आम तौर पर मैं गेटर्स के साथ पूरी तरह से ठीक हूं और अगर ए। वे कुछ अनोखा और / या बी करते हैं। आपके पास केवल एक है, हाँ, आप एक सार्वजनिक अंतिम और वह सब कुछ कर सकते हैं, लेकिन nah
फेसलेसटीगर

1
इसके साथ लाभ यह है कि आप इंटरफ़ेस को बदले बिना, वर्ग के आंतरिक को बदल सकते हैं। कहते हैं, तीन गुणों के बजाय, आपके पास एक था - तार की एक सरणी। यदि आप गेटर्स और सेटर का उपयोग कर रहे हैं, तो आप वह परिवर्तन कर सकते हैं, और फिर गेटटर / सेटर को अपडेट कर सकते हैं ताकि पता चल सके कि नाम [0] पहला नाम है, नाम [1] बीच का है, आदि लेकिन यदि आपने अभी सार्वजनिक गुणों का उपयोग किया है , आपको हर वर्ग की पहुंच वाले कर्मचारी को भी बदलना होगा, क्योंकि पहले जिस संपत्ति का वे उपयोग कर रहे हैं वह अब मौजूद नहीं है।
एंड्रयू होव्स

1
@AndrewHows मैंने वास्तविक जीवन में जो कुछ देखा है, जब लोग क्लास के आंतरिक हिस्से को बदलते हैं तो वे भी इंटरफ़ेस बदलते हैं और सभी कोड का एक बड़ा रीफैक्टरिंग करते हैं
एल्डोसा

2

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


मैं एक महंगा ऑपरेशन होने के लिए कभी भी गटर या सेटर की उम्मीद नहीं करता। ऐसे मामलों में बेहतर एक कारखाने का उपयोग करें: आप की जरूरत सभी निपटान का उपयोग करें और फिर महंगी executeया buildविधि का आह्वान करें ।
ह्यूबर्ट ग्रौस्सोवाकियाक

2

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

दूसरी ओर, यदि सदस्य सार्वजनिक है, तो उपकरण सदस्य के लिए रीड / राइट एक्सेस को फ़िल्टर करना संभव नहीं बनाते हैं। इसलिए आपको सदस्य के सभी उपयोगों को ट्रूड करना होगा।


आप सही क्लिक कर सकते हैं> किसी सदस्य पर ठीक उसी तरह से उपयोग पा सकते हैं जैसे एक
गेट्टर

2

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


1

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


2
मुझे लगता है कि गेट्टर या सेटर का व्यवहार बदलना तब एक परिवर्तन नहीं है। </ कटाक्ष>
आर। मार्टिनो फर्नांडीस

@ R.MartinhoFernandes हमेशा होना जरूरी नहीं है। TBYS
फिल

1

मैं सिर्फ एनोटेशन के विचार को फेंकना चाहूंगा: @getter और @setter। @Getter के साथ, आपको obj = class.field नहीं बल्कि class.field = obj में सक्षम होना चाहिए। @Setter के साथ, इसके विपरीत। @Getter और @setter के साथ आपको दोनों करने में सक्षम होना चाहिए। यह इनकैप्सुलेशन को संरक्षित करेगा और रनटाइम पर तुच्छ तरीकों को न कहकर समय को कम करेगा।


1
इसे "तुच्छ तरीकों" के साथ रनटाइम पर लागू किया जाएगा। दरअसल, शायद गैर-तुच्छ।
फिल

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