2013-08-22 12 views
12

बेस कक्षा:विरासत और वस्तु निर्माण

public class Inheritance { 
    int i; 
    Inheritance() { 
     System.out.println("I am in base class" + i); 
    } 
} 

व्युत्पन्न वर्ग:

public class TestInheritance extends Inheritance { 

    TestInheritance() { 
     System.out.println("I am in derived class"); 
    } 

    public static void main(String[] args) { 
     TestInheritance obj = new TestInheritance();   
    } 
} 

यह है कि मैं क्या के बारे में क्या ऊपर चल रहा है मन में है है।

जब मैं डिफ़ॉल्ट super() द्वारा व्युत्पन्न कक्षा का ऑब्जेक्ट बनाता हूं तो कॉल क्लास के कन्स्ट्रक्टर को कॉल किया जाता है और यह चर i को प्रारंभ करता है।

अब, मेरा सवाल है: क्या इस मामले में निर्माता केवल i परिवर्तनीय प्रारंभ करता है और कक्षा का ठोस वस्तु नहीं बनाता है?

जो मैंने अभी तक पढ़ा है उससे केवल एक ही वस्तु बनाई गई है - व्युत्पन्न कक्षा में जिसमें i वैरिएबल है।

लेकिन उस समय से बेस क्लास के निर्माता को बुलाया जाता है और उस बिंदु पर जहां व्युत्पन्न वर्ग के निर्माता को i स्मृति में संग्रहीत किया जाता है?

और यह मामला क्या होगा जिसमें आधार वर्ग एक सार है।

अगर मैं जान सकता हूं कि समय के विभिन्न बिंदुओं पर स्मृति में क्या होता है तो मैं वास्तव में सराहना करता हूं।

यदि मैंने कुछ ऐसा कहा है जो मौलिक रूप से गलत है तो कृपया मुझे बताएं। मैं वास्तव में जानना चाहता हूं कि यह काम कैसे काम करता है।

+16

@ पैनिज़ उह ... हाँ यह है? – asteri

+1

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

+3

+1 - एक अच्छी तरह से संरचित प्रश्न - सटीक, विशिष्ट प्रश्न पूछना। –

उत्तर

4

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

अब, तार्किक भाग के बारे में पर्याप्त कहा, चलिए भौतिक भाग की जांच करें। एकल (शारीरिक) वस्तु स्मृति

+--------------------------+----------------------------+ 
|    B   |    C'   + 
+--------------------------+----------------------------+ 

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

अब, अगर बी अपनी ही सुपर क्लास एक था, संरचना इस तरह हो गया होता:

+--------+-----------------+----------------------------+ 
| A |  B'   |    C'   + 
+--------+-----------------+----------------------------+ 

यहाँ क्या नोट करना महत्वपूर्ण है कि B == A + B' है। दूसरे शब्दों में, सी को ए के बारे में जानने की आवश्यकता नहीं है। यह सब इसकी परवाह करता है यह तत्काल सुपरक्लास बी है, जो इसकी आंतरिक संरचना को छुपाता है।

प्रश्नों का उत्तर प्राप्त करने के लिए:

इस मामले में निर्माता केवल चर मैं प्रारंभ करता है और वर्ग का एक ठोस वस्तु का निर्माण नहीं करता?

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

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

I am in base class 0 
I am in derived class 

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

जो मैंने अभी तक पढ़ा है, उससे केवल एक ही वस्तु बनाई गई है - व्युत्पन्न कक्षा में जिसमें मैं चरक हूं।

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

लेकिन उस समय से बेस क्लास के निर्माता को बुलाया जाता है और उस समय बिंदु जहां व्युत्पन्न वर्ग के निर्माता को स्मृति में कैसे/कहाँ रखा जाता है?

जब new TestInheritance() निष्पादित किया जाता है, पहली बात यह है कि, पहले ही पूरी हो कंस्ट्रक्टर्स कहा जाता है, पहले भी प्रारंभ किया जाता है, कि स्मृति पूरी वस्तु के लिए आवंटित किया गया है। - आमतौर पर यह स्मृति "गंदा" होती है और यही कारण है कि इसे प्रारंभ करने की आवश्यकता है। - TestInheritance के फ़ील्ड, इसके सुपरक्लास 'फ़ील्ड आदि के लिए जगह है। स्मृति में वस्तु के भीतर प्रत्येक फ़ील्ड की स्थिति भी पहले से ही जानी जाती है।

तो, बेस क्लास के निर्माता के नाम से पहले भी i और किसी अन्य क्षेत्र के लिए आवंटित स्मृति है, बस वे "गंदे" (आरंभ नहीं किए गए) हैं।

और यह मामला क्या होगा जिसमें आधार वर्ग एक सार है।

कोई फर्क नहीं पड़ता। केवल एक ही है कि आप स्वयं द्वारा एक अमूर्त वर्ग की वस्तुएं नहीं बना सकते हैं। आप उन्हें एक (कंक्रीट) उपclass के हिस्से के रूप में बनाते हैं। यह इस तथ्य के समान है कि एक नया इंसान अपने आप से पैदा नहीं हो सकता है। यह या तो एक बच्ची या एक बच्चा है।

मैं वास्तव में सराहना करता हूं अगर मैं जान सकता हूं कि विभिन्न बिंदुओं पर स्मृति में क्या होता है।

मुझे उम्मीद है कि मैंने किया था।

यदि मैंने कुछ ऐसा कहा है जो मौलिक रूप से गलत है तो कृपया मुझे बताएं। मैं वास्तव में जानना चाहता हूं कि यह काम कैसे काम करता है।

कुछ भी "मौलिक रूप से गलत" नहीं है।

+0

प्रश्नों के युगल- क्या सुपर() डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करता है यह डिफ़ॉल्ट कन्स्ट्रक्टर क्या करता है? और आप में उन क्षेत्रों को स्पष्टीकरण दिया गया है जो सुपर क्लास बी से आ रहे हैं, जो उन्हें शुरू कर रहे हैं, सी 'कन्स्ट्रक्टर या बी के कन्स्ट्रक्टर? और यह भी कहना सही है कि बी का उद्देश्य सी के अंदर निहित है? – Prateek

+0

मेरी इच्छा है कि मेरा आभार व्यक्त करने के और तरीके थे। धन्यवाद!!! – Prateek

2

मुझे लगता है कि यह विरासत पर भ्रम का एक आम क्षेत्र है। ऐसा लगता है कि आपने केवल एक वस्तु बनाई है, यह सही है।

मैं अनुशंसा करता हूं कि आप बेस क्लास में आवृत्ति चर के बारे में सोचें, जैसा कि किसी भी सुपरक्लास में निहित है, जैसे बेस क्लास में किसी भी सार्वजनिक या संरक्षित विधि सुपरक्लास से पहुंच योग्य है।

जब किसी ऑब्जेक्ट को तुरंत चालू किया जाता है, तो जावा रनटाइम वह सब कुछ करता है जो भंडारण की आवश्यकता होती है - अधिकतर आवृत्ति चर के लिए भंडारण की आवश्यकता होती है। इसलिए बेस क्लास में इंस्टेंस वैरिएबल को स्मृति के ब्लॉक का हिस्सा माना जा सकता है जिसमें ऑब्जेक्ट के लिए सभी इंस्टेंस वेरिएबल्स शामिल हैं, चाहे वे सबक्लास या सुपरक्लास में घोषित हों।

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

+0

+1 अच्छा स्पष्टीकरण! – alfasin

+0

संकल्पनात्मक रूप से मैं पूरी तरह से आपके बिंदु को समझ गया। हालांकि मेरे पास कुछ सवाल है। क्या होता है जब आधार वर्ग एक सार है? उस मामले में सुपर() व्युत्पन्न कक्षा में क्या करता है। – Prateek

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