दिलचस्प पोस्ट
C ++ में सरणियों के लिए एक विशिष्ट मात्रा में स्मृति आवंटित करने का क्या उद्देश्य है? ग्रहण 3.7 से 4.2 (जूनो) को अपग्रेड करने का सबसे आसान तरीका pythonw.exe या python.exe? कोणीय UI राउटर: माता-पिता निराधार ऑब्जेक्ट के आधार पर बाल राज्य टेम्पलेट तय करें PHP memory_limit बढ़ाना किस बिंदु पर यह पागल हो जाता है? क्यों कमजोर NSString गुण आईओएस में जारी नहीं हो? मैं कैपिस्ट्रैनो से एक रेक काम कैसे चलाऊं? सभी सामान्य अपरिभाषित व्यवहार क्या हैं जो एक सी ++ प्रोग्रामर के बारे में जानना चाहिए? HTML5 में पॉलीफिल का क्या अर्थ है? एएसपी.नेट एमवीसी में रूटिंग, यूआरएल में यूज़रनेम दिखा रहा है पायथन में कार्यात्मक रूप से प्रोग्राम क्यों? केस असंवेदनशील 'में' – पायथन रेल 3.1 और रूबी 1.9.3p125: रूबी-डीबग19 अभी भी "प्रतीक नहीं मिला: _ruby_threadptr_data_type" के साथ क्रैश करता है एक्सेल वीबीए में एक वैश्विक चर का जीवनकाल क्या है? डेटा फ्रेम से पंक्ति नामों का प्रदर्शन हटाया जा रहा है

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

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

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

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 

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

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

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

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

Solutions Collecting From Web of "एक वर्ग के उदाहरण चर को छिपाते हुए"

जावा में, डेटा सदस्य बहुरूपक नहीं हैं। इसका मतलब यह है कि 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; आप कंपाइलर कह रहे हैं "यह ऑब्जेक्ट का इलाज करें जैसे कि यह मूल के एक उदाहरण थे"

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

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

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

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

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