दिलचस्प पोस्ट
पाठ फ़ाइल की अंतिम पंक्ति को तुरंत पढ़ें? जीमेल एसएमटीपी सर्वर का उपयोग करते समय से पता बदलने के लिए यूआईएलबल में लाइन रिक्ति को कैसे नियंत्रित किया जाए JComboBox तालिका संपादक को कैसे बनाने के लिए एक साधारण जेसीम्बोबॉक्स का डिज़ाइन है? एंड्रॉइड एमुलेटर में एपीके फ़ाइल कैसे स्थापित करें? "वार्म-अप" इकाई फ़्रेमवर्क कैसे करें? इसे "ठंड" कब मिलता है? जावा में वैध @SuppressWarnings चेतावनी नामों की सूची क्या है? आईओएस 9 यूआरएल SCHEME के ​​साथ Instagram ऐप खोलने नहीं अमेज़ॅन रूटे 53 में DNS आधारित यूआरएल अग्रेषण सेट अप करें वेबसाइट होस्ट करने के लिए IIS एक्सप्रेस का इस्तेमाल करना (अस्थायी तौर पर) आईफोन के लिए मुद्रा को स्थानीय बनाना सिंक्रनाइज़ेशन कॉन्टैक्ट। मुख्य यूआई धागे पर निरंतरता में निरर्थक है विंडोज पर PHP और अपाचे के लिए Imagick स्थापित करें पायथन 3 वेब स्क्रैपिंग में HTTP त्रुटि 403 एंड्रॉइड टाइमर एक टेक्स्टव्यू अपडेट करना (यूआई)

एक वर्ग के उदाहरण चर को छिपाते हुए

मैं सोच रहा हूं कि जावा को एक सुपर-क्लास के बारे में यह अजीब व्यवहार और एक ही नाम के साथ उदाहरण वाले चर वाले उपवर्ग हैं।

मान लें कि हमारे पास निम्न श्रेणी की परिभाषाएं हैं:

class Parent { int var = 1; } class Child extends Parent { int var = 2; } 

ऐसा करने से, हम सुपर वर्ग की वैरिएबल var को छिपाते हैं। और अगर हम एक super कॉल के माध्यम से Parent के var को एक्सेस करने के लिए स्पष्ट रूप से निर्दिष्ट नहीं करते हैं, तो हमें कभी भी बाल को किसी बच्चे के उदाहरण से नहीं प्राप्त करना चाहिए।

लेकिन जब हमारे पास एक कास्ट होता है, तो यह छिपाई तंत्र टूट जाता है:

 Child child = new Child(); Parent parent = (Parent)child; System.out.println(parent.var); // prints out 1, instead of 2 

क्या यह पूरी तरह से क्षेत्र छिपाने के पूरे बिंदु को नाकाम नहीं करता है? यदि यह मामला है, तो क्या यह विचार पूरी तरह से बेकार नहीं है?

संपादित करें : मैं जावा ट्यूटोरियल में इस लेख के लिए विशेष रूप से संदर्भित कर रहा हूँ। इसका उल्लेख है

उप-कक्षा में, सुपर-क्लास में फ़ील्ड को उसके सरल नाम से संदर्भित नहीं किया जा सकता है। इसके बजाय, क्षेत्र को सुपर के माध्यम से पहुंचाया जाना चाहिए …

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

वेब के समाधान से एकत्रित समाधान "एक वर्ग के उदाहरण चर को छिपाते हुए"

जावा में, डेटा सदस्य बहुरूपक नहीं हैं। इसका मतलब यह है कि Parent.varParent.var और Child.var दो अलग-अलग चर हैं जो समान नाम हैं। आप व्युत्पन्न वर्ग में किसी भी तरह से "ओवरराइडिंग" var ; जैसा कि आपने स्वयं की खोज की है, दोनों चर एक दूसरे से स्वतंत्र रूप से उपयोग किए जा सकते हैं

सबसे अच्छा तरीका आगे वास्तव में आप क्या हासिल करने की कोशिश कर रहे हैं पर निर्भर करता है:

  1. यदि Parent.var को Child दिखाई नहीं दे, तो इसे private बनाएं।
  2. यदि Parent.varParent.var और Child.var दो तर्कसंगत अलग चर हैं, तो भ्रम से बचने के लिए उन्हें अलग-अलग नाम दें।
  3. अगर Parent.varParent.var और Child.var समान वैरिएबल हैं, तो उसके लिए एक डाटा सदस्य का उपयोग करें।

फ़ील्ड छिपाने का "बिंदु" केवल कोड के व्यवहार को निर्दिष्ट करने के लिए है, जो एक वैरिएबल को उसके सुपर क्लास में एक जैसा नाम देता है।

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

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

 class Parent { private int var = 1; public int getVar() { return var; } public void setVar(int var) { this.var = var; } } class Child extends Parent { private int var = 2; public int getVar() { return var; } public void setVar(int var) { this.var = var; } } 

और अब, यह परीक्षण करते समय, हमें वांछित परिणाम मिलता है, 2:

  Child child = new Child(); Parent parent = (Parent)child; System.out.println(parent.getVar()); 

जब आप कास्टिंग कर रहे हैं, तो आप संकलक को "मैं बेहतर जानता हूं" को प्रभावी ढंग से बताता हूं – यह सामान्य मजबूत-टाइपिंग निष्कर्ष नियम निलंबित करता है और आपको एक संदेह का लाभ देता है

Parent parent = (Parent)child; कह कर Parent parent = (Parent)child; आप कंपाइलर कह रहे हैं "यह ऑब्जेक्ट का इलाज करें जैसे कि यह मूल के एक उदाहरण थे"

एक और नोट पर, आप ओओ (अच्छे!) के सिद्धांत "जानकारी छिपाना" को भ्रमित कर रहे हैं, फ़ील्ड-छुपा साइड इफेक्ट (आमतौर पर खराब) के साथ।

जैसा कि आपने बताया:

हम सुपरक्लास के वैरिएबल वेर को छिपाते हैं

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

एक साइड नोट के तौर पर मैं कहूंगा कि यह वास्तव में भ्रमित है और मान्य वाक्यविन्यास के रूप में अनुमति नहीं दी जानी चाहिए।