2011-11-10 22 views
8

मैं 2 साल के लिए एक नेट कोडर (कह सकता हूं कि मैं प्रोग्रामर हूं) नहीं रहा हूं। एक सवाल है कि मैं वर्षों से समझ नहीं पा रहा हूं, इस प्रकार बेस क्लास का एक उदाहरण व्युत्पन्न वर्ग का उदाहरण कैसे रख सकता है?आधार वर्ग का एक उदाहरण व्युत्पन्न वर्ग का उदाहरण कैसे रख सकता है?

class BaseClass 
{ 
    public A propertyA; 
    public B propertyB; 
} 

class DerivedClass :BaseClass 
{ 
    public C propertyC; 

} 

यह कैसे हो सकता है:

BaseClass obj = new DerivedClass() 

मेरा मतलब है, BaseClass की स्मृति मॉडल, नए जोड़े propertyC लिए कोई जगह नहीं है, तो कैसे कर सकता

मान लीजिए हम दो वर्गों है यह अभी भी संपत्ति सी के मूल्य पकड़ो?

दूसरी ओर, यह कैसे हो नहीं कर सकते कर सकते हैं:

DerivedClass obj = new BaseClass() 

मुझे लगा कि यह सही तरीका के बाद से DerivedClass की स्मृति मॉडल BaseClass के लिए और भी अधिक सभी रिक्त स्थान है। लेकिन यह सच नहीं है, क्यों?

मैं जानता हूँ कि मैं एक बहुत बेवकूफ सवाल पूछ रहा हूँ, लेकिन किसी ने मुझे इस के और अधिक विस्तार जवाब दे सकता है? यह स्मृति या कंपाइलर के परिप्रेक्ष्य से बेहतर होगा।

+0

यह आपके प्रश्न के बहुत अच्छे लिखित उत्तर के साथ, इस प्रश्न के समान ही है। http://stackoverflow.com/questions/4937180/a-base-class-pointer-can-point-to-a-derived-class-object-why-is-the-vice-versa – darnir

+0

आपके उत्कृष्ट के लिए धन्यवाद जवाब! मुझे बिंदु मिल गया है :) आप सभी को धन्यवाद !!! ~ – NextStep

उत्तर

5

क्योंकि (और इस अवधारणा को अक्सर गलत समझा जाता है) सूचक जो पॉइंटर धारण करता है वह ऑब्जेक्ट के वास्तविक ठोस प्रकार से स्वतंत्र रूप से टाइप किया जाता है।

तो तुम जब लिखने

BaseClass obj = new DerivedClass() 

बात यह है कि कहते हैं BaseClass obj एक नया संदर्भ चर ढेर कि संकलक BaseClass से कुछ है जो, या व्युत्पन्न के लिए एक संदर्भ पकड़ करने के लिए, को समझता है पर बनाता है।

बात यह है कि = new DerivedClass() पढ़ता है वास्तव में प्रकार DerivedClass की एक नई वस्तु, ढेर पर यह भंडार बनाता है, और स्मृति स्थान कि obj अंक करने के लिए उस वस्तु के लिए एक सूचक संग्रहीत करता है। हीप पर वास्तविक वस्तुDerivedClass है; इसे ऑब्जेक्ट के कंक्रीट प्रकार के रूप में जाना जाता है।

परिवर्तनीय objBaseClass प्रकार का घोषित किया गया है। यह एक ठोस प्रकार नहीं है, यह सिर्फ एक वैरिएबल प्रकार है, जो केवल चर में एक पते संग्रहीत करने से संकलक प्रतिबंधित करती है कि करने के लिए अंक एक वस्तु है जो एक BaseClass नहीं है या किस प्रकार से निकाले जाते हैं नहीं करता है BaseClass

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

4

BaseClass एक संदर्भ प्रकार है, objBaseClass ऑब्जेक्ट नहीं है। यह संदर्भBaseClass ऑब्जेक्ट पर है। विशेष रूप से, यह के BaseClass भाग का संदर्भ है।

+0

मुझे अन्य सभी उत्तरों को समझने के बाद, मुझे आपका अंक मिला :) धन्यवाद। – NextStep

2

जब आप कहते हैं कि यह:

BaseClass obj = new DerivedClass() 

आप नहीं कह रहे हैं "एक कंटेनर बनाएं इस BaseClass वस्तु को रोकने के लिए, और फिर रटना इस बड़ी DerivedClass इसे में वस्तु"।

आप वास्तव में एक DerivedClass ऑब्जेक्ट बना रहे हैं, और यह एक DerivedClass ऑब्जेक्ट के लिए पर्याप्त स्मृति स्थान में बनाया जा रहा है। .NET फ्रेमवर्क इस तथ्य का ट्रैक कभी नहीं खोता है कि यह बात विशेष रूप से एक व्युत्पन्न क्लास है, और न ही यह कभी भी इस तरह से इलाज करना बंद कर देता है।

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

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

+0

यह वास्तव में एक मजाकिया और उत्तर समझने में आसान है। धन्यवाद! :) – NextStep

+0

उदाहरण के लिए +1! – Lazer

0

जवाब किसी दूसरे उपयोगकर्ता से जेबी, ने एक ही प्रश्न पर लिखा है, जो स्टैक ओवरफ्लो पर एक ही प्रश्न पर लिखा है।

यदि मैं आपको बताता हूं कि मेरे पास एक कुत्ता है, तो आप सुरक्षित रूप से यह मान सकते हैं कि मेरे पास एक कुत्ता है।

यदि मैं आपको बताता हूं कि मेरे पास पालतू जानवर है, तो आप नहीं जानते कि वह जानवर कुत्ता है, यह बिल्ली या शायद एक जिराफ भी हो सकता है। कुछ अतिरिक्त जानकारी जानने के बिना आप सुरक्षित रूप से यह नहीं मान सकते कि मेरे पास एक कुत्ता है।

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

मान लीजिए आप अब मुझे मेरे पालतू के लिए एक उपहार खरीदना चाहते हैं (चरमराती अब आप सुनेंगे खींच सादृश्य है)।

पहले परिदृश्य में आपको पता है कि यह एक कुत्ता है, आप मुझे एक पट्टा खरीद सकते हैं, सभी खुश हैं।

दूसरे परिदृश्य मैंने तुम्हें बताया नहीं किया है क्या मेरे पालतू इतना है अगर आप मुझे एक उपहार वैसे भी खरीदने के लिए जा रहा है कि आप जानकारी मैं havent तुमसे कहा था (या बस लगता है) पता करने की जरूरत है, तो आप मुझे एक खरीद पट्टा, अगर यह निकलता है तो मैं वास्तव में में एक कुत्ता था हर कोई खुश है।

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

+0

मुझे आपका अंक भी मिला, धन्यवाद :) – NextStep

0

इस तरह स्मृति की वजह से संभव है आधार और व्युत्पन्न कक्षाओं के लिए आवंटित किया गया है। व्युत्पन्न वर्ग में, बेस क्लास के आवृत्ति चर पहले आवंटित किए जाते हैं, इसके बाद व्युत्पन्न वर्ग के आवृत्ति चर के बाद। जब बेस क्लास रेफरेंस वैरिएबल को व्युत्पन्न क्लास ऑब्जेक्ट को असाइन किया जाता है, तो यह बेस क्लास इंस्टेंस वेरिएबल्स को देखता है, जो कि "अतिरिक्त" व्युत्पन्न क्लास इंस्टेंस चर के साथ अपेक्षा करता है।

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