एक ही कक्षा में किसी अन्य ऑब्जेक्ट के निजी क्षेत्र तक पहुंचें


91
class Person 
{
   private BankAccount account;

   Person(BankAccount account)
   {
      this.account = account;
   }

   public Person someMethod(Person person)
   {
     //Why accessing private field is possible?

     BankAccount a = person.account;
   }
}

कृपया डिज़ाइन के बारे में भूल जाएं। मुझे पता है कि OOP निर्दिष्ट करता है कि निजी वस्तुएं वर्ग के लिए निजी हैं। मेरा सवाल यह है कि OOP को ऐसे क्यों डिज़ाइन किया गया था कि निजी क्षेत्रों में कक्षा-स्तरीय पहुंच है न कि वस्तु-स्तरीय पहुंच ?


5
मेरा मानना ​​है कि ओपी "पर्सन" ऑब्जेक्ट को "someMethod" करने के लिए एक अलग ऑब्जेक्ट माना जाता है, और इसलिए इस विधि की निजी सदस्यों तक पहुंच नहीं होनी चाहिए ... भले ही यह "पर्सन" क्लास के भीतर हो।
Inisheer

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

someMethodमान्य नहीं है। यह कुछ भी वापस नहीं करता है। यह होना ही चाहिए void
निकोलस बारबुल्स्को

1
यदि यह मामला नहीं था, तो कॉपी कंस्ट्रक्टर और असाइनमेंट ऑपरेटर imo लिखना बहुत कठिन होगा।
रोजिना

जवाबों:


68

मैं भी उत्तर से थोड़ा उत्सुक हूं।

सबसे संतोषजनक जवाब जो मुझे मिलता है वह आर्टेमिक्स से एक अन्य पोस्ट में है (मैं एसीलैस को पर्सन क्लास के साथ बदल रहा हूं): ऑब्जेक्ट-लेवल के बजाय क्लास-लेवल एक्सेस मॉडिफायर्स क्यों हैं?

निजी संशोधक एनकैप्सुलेशन सिद्धांत को लागू करता है।

विचार यह है कि 'बाहरी दुनिया' को व्यक्ति की आंतरिक प्रक्रियाओं में बदलाव नहीं करना चाहिए क्योंकि समय के साथ व्यक्ति कार्यान्वयन बदल सकता है (और आपको कार्यान्वयन में अंतर को ठीक करने के लिए पूरी बाहरी दुनिया को बदलना होगा - जो लगभग असंभव है)।

जब व्यक्ति का उदाहरण अन्य व्यक्ति के उदाहरण तक पहुँचता है - तो आप यह सुनिश्चित कर सकते हैं कि दोनों उदाहरण हमेशा व्यक्ति के कार्यान्वयन के विवरण को जानते हैं। यदि आंतरिक से व्यक्तिगत प्रक्रियाओं के तर्क को बदल दिया जाता है - आपको बस इतना करना होगा कि व्यक्ति के कोड को बदल दें।

संपादित करें: कृपया आर्टेमिक्स के जवाब को वोट करें । मैं सिर्फ इसे कॉपी-पेस्ट कर रहा हूं।


4
शायद यही कारण है। लेकिन यह एक बुरा विचार है । यह बुरे अभ्यास को प्रोत्साहित करता है। Personकक्षा में, के क्षेत्र तक पहुँचने वाले डेवलपर Personको पूरी कक्षा के कार्यान्वयन को जानना नहीं है। अच्छा अभ्यास एक्सेसर का उपयोग करना है, यह जानने के बिना कि एक्सेसर क्या संचालन करता है।
निकोलस बारबुल्स्को

16
@ नाइकोलाब बार्बुल्स्को मुझे लगता है कि उत्तर में दिया गया कारण ध्वनि है। उदाहरण के लिए कहें कि आप किसी अन्य उदाहरण के साथ किसी वस्तु equals(Object)की समानता की जांच करने के लिए जावा वर्ग में विधि को लागू करना चाहते हैं । यदि आप दो उदाहरणों के बराबर हैं, तो आप बाहरी दुनिया की जांच करने में सक्षम होना चाह सकते हैं, लेकिन आप सार्वजनिक पहुँच के तरीकों का उपयोग करके बाहरी दुनिया में समानता की जाँच के लिए आवश्यक सभी वर्ग के निजी क्षेत्रों को उजागर नहीं करना चाह सकते हैं। खेतों में कक्षा-स्तरीय पहुंच इस तरह के सार्वजनिक तरीकों को लागू करने के लिए प्रेरित आवश्यकता के बिना इस तरह के तरीके को लागू करने में सक्षम बनाता है। PersonPersonprivate
माल्ट स्कोर्पुपा

1
@ माल्टेस्कॉर्प - यह एक अच्छा उदाहरण है (विधि को लागू करते हुए equals)।
निकोलस बारबुलेसको

@MalteSkoruppa - हालांकि, निजी अभिगमकर्ताओं को बुलाकर विधि equalsको लागू किया जा सकता है।
निकोलस बारबुल्स्को

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

17

जावा भाषा विनिर्देश देखें , खंड 6.6.1। पहुँच का निर्धारण

य़ह कहता है

अन्यथा, यदि सदस्य या कंस्ट्रक्टर घोषित किया जाता है private, तो एक्सेस की अनुमति दी जाती है, यदि केवल और अगर यह शीर्ष स्तर वर्ग (class7.6) के निकाय के भीतर होता है, जो सदस्य या कंस्ट्रक्टर की घोषणा को संलग्न करता है।

अधिक जानकारी के लिए ऊपर दिए गए लिंक पर क्लिक करें। तो जवाब है: क्योंकि जेम्स गोस्लिंग और जावा के अन्य लेखकों ने इसे उसी तरह से तय किया।


16

अच्छा प्रश्न। ऐसा लगता है कि ऑब्जेक्ट स्तर पहुंच संशोधक आगे भी एनकैप्सुलेशन सिद्धांत को लागू करेगा।

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

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


2
इस जवाब को वोट देने की जरूरत है! अन्य जवाब सिर्फ 'नियम' को फिर से बताते हैं लेकिन केवल यह वास्तव में नियम के पीछे के कारण को उजागर करता है और बिंदु को हिट करता है।
mzoz

4
लेकिन क्या यह बेहतर नहीं होगा कि कोई वस्तु स्वयं की प्रतियां प्रदान करने के लिए जिम्मेदार हो? फिर, यदि आपको किसी वस्तु की गहरी प्रतिलिपि की आवश्यकता है, तो इससे कोई फर्क नहीं पड़ता कि आप एक ही वर्ग के किसी अन्य ऑब्जेक्ट या किसी भिन्न वर्ग के ऑब्जेक्ट हैं: यह एक ही तंत्र है, o.deepCopy()या जो भी हो।
dirtside

4

यह काम करता है क्योंकि आप में हैं class Person- एक वर्ग के अंदर प्रहार करने की अनुमति दी जाती है यह स्वयं का वर्ग है। यह वास्तव में मदद करता है जब आप एक कॉपी कंस्ट्रक्टर लिखना चाहते हैं, उदाहरण के लिए:

class A
{
   private:
      int x;
      int y;
   public:
      A(int a, int b) x(a), y(b) {}
      A(A a) { x = a.x; y = y.x; }
};

या अगर हम लिखना चाहते हैं operator+और operator-हमारे बड़ी संख्या वर्ग के लिए।


यह निर्भरता इंजेक्शन के समान है। जिसमें आप कुछ अन्य वर्ग की वस्तु को भी इंजेक्ट कर सकते हैं, जहाँ आप निजी चर का उपयोग नहीं कर सकते हैं।
नागेश्वरन

निश्चित रूप से, यदि आप कक्षा B के ऑब्जेक्ट से वर्ग A का निर्माण करने का प्रयास कर रहे हैं, और B के पास निजी घटक है, तो A को मित्र घोषित करने की आवश्यकता है, या केवल सार्वजनिक भागों को देख सकता है [संभवतः संरक्षित, यदि A को B से लिया गया है। ]।
मैट पीटरसन

जावा और .net में दोस्त की कोई अवधारणा नहीं है। ऐसे मामलों में, इसे कैसे संभालना है?
नागेश्वरन

1

जावा में निजी दृश्यता के शब्दार्थ को वस्तु स्तर के बजाय कक्षा स्तर पर क्यों रखा गया है, इस सवाल पर मेरे 2 सेंट।

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

सच में, मैं न तो मनगढ़ंत कर पा रहा था और न ही ऐसा उदाहरण खोज पा रहा था कि कक्षा-निजी स्तर पर दृश्यता (जैसे जावा द्वारा प्रस्तुत) वस्तु-निजी स्तर पर दृश्यता की तुलना में कोई समस्या पैदा करे।

कहा कि, दृश्यता नीतियों की अधिक बारीक प्रणाली के साथ प्रोग्रामिंग भाषाएं वस्तु स्तर और वर्ग स्तर पर वस्तु दृश्यता दोनों को वहन कर सकती हैं।

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

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

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


0

क्योंकि private एक्सेस संशोधक इसे केवल कक्षा के भीतर दिखाई देता है । यह विधि अभी भी कक्षा में है


मेरा सवाल यह है कि इसे "कक्षा के भीतर" की तरह क्यों बनाया गया है लेकिन "केवल वस्तु के भीतर" ही क्यों नहीं?
नागेश्वरन

क्योंकि ऐसा ही जावा बनाया जाता है।
दर्जन

और जावा ने जावा को ऐसा क्यों बनाया?
नागेश्वरन

जावा ने नहीं बनाया, जावा के रचनाकारों ने किया। क्यों? क्योंकि वे चट्टान!
दरिज़न

जावा निर्माता बिना किसी कारण के ऐसा नहीं करेंगे, और ऐसा करने के लिए कुछ कारण होना चाहिए; मैं कारण पूछ रहा हूँ
नागेश्वरन

0

privateक्षेत्र वर्ग / वस्तु, जिसमें क्षेत्र घोषित किया जाता है में पहुँचा जा सकता है। यह उस स्थित से बाहर अन्य वर्गों / वस्तुओं के लिए निजी है, जिसमें यह स्थित है।


-1

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


-2

जावा में प्रतिबिंब अवधारणा के साथ फ़ील्ड और विधियों को निजीकृत करना संभव है

मोडिकंडो मेटोडोस वाई कैंपोस प्राइवेटडोस कॉन रिफ्लेक्शन एन जावा


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