दोनों वक्तव्यों में आप उल्लेख करते हैं कि Dog
के डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करना शामिल है; इसलिए, यह स्पष्ट है कि दोनों मामलों में Dog
उदाहरण बनाया गया है। इसका मतलब है कि दोनों कथन को एक समान उदाहरण के साथ एक चर प्रारंभ करने के लिए समाप्त होते हैं (यह बराबर के बाद बयान का हिस्सा है)।
हालांकि, बयान में एक और हिस्सा भी है: एक चर की घोषणा (यह बराबर से पहले बयान का हिस्सा है)।
object a = new Dog(); // static type: object/runtime type: Dog
Dog b = new Dog(); // static type: Dog/runtime type: Dog
संकलक है कि यह साबित नहीं कर सकते आप एक चर को कोई मान निर्दिष्ट करने की अनुमति नहीं: इस तरह के सी # के रूप में स्थिर टाइप किया भाषाओं में, हर चर - - अधिक आम तौर पर, किसी भी अभिव्यक्ति एक स्थिर प्रकार है परिवर्तनीय के स्थिर प्रकार का है, उदाहरण के लिए यह
Cat c = new Dog(); // unless Dog derives from Cat, which we know isn't true
के बाद से सभी reference types परोक्ष System.Object
से निकाले जाते हैं की अनुमति नहीं होगी, स्थिर प्रकार का एक चर object
ठीक है के लिए एक Dog
बताए। आप "स्थैतिक प्रकार" के बारे में सोच सकते हैं क्योंकि वस्तु "घोषित" है। आप स्रोत कोड पढ़कर बस के स्थिर प्रकार का निर्धारण कर सकते हैं; इस तरह संकलक यह करता है।
फिर ऊपर वर्णित प्रत्येक चर (अभिव्यक्ति) के रनटाइम प्रकार भी है। यह दोनों मामलों में समान है, क्योंकि दोनों मामलों में हमने Dog
बनाया है। आप "रनटाइम प्रकार" के बारे में सोच सकते हैं क्योंकि वास्तव में ऑब्जेक्ट है। कुछ रनटाइम प्रकार केवल स्रोत को पढ़कर निर्धारित नहीं किया जा सकता है; जब आप प्रोग्राम चल रहे हों, तो आप केवल यह निर्धारित करेंगे, इसलिए नाम। सी # में, यह GetType
पर कॉल करके किया जाता है।
यह स्पष्ट होना चाहिए कि रनटाइम प्रकार ऐसा कुछ है जिसे आप बिना नहीं कर सकते; सब कुछ सब के बाद कुछ "होना" है। लेकिन स्थिर प्रकार की धारणा का आविष्कार करने के साथ परेशान क्यों?
आप static types के बारे में सोच सकते हैं जो आपके (प्रोग्रामर) और कंपाइलर के बीच अनुबंध के रूप में है। b
के स्थिर प्रकार को Dog
होने की घोषणा करके, आप संकलक को बताते हैं कि आप Dog
के अलावा किसी अन्य चीज़ को संग्रहीत करने के लिए उस चर का उपयोग करने का इरादा नहीं रखते हैं। बदले में, संकलक, आपको अपने निर्दिष्ट उद्देश्य का उल्लंघन करने नहीं देता है और यदि आप ऐसा करने का प्रयास करते हैं तो एक त्रुटि उत्पन्न करता है। यह आपको d
का उपयोग करने से भी रोकता है, प्रत्येकDog
का समर्थन करना चाहिए।
पर विचार करें:
class Dog {
public void Woof();
}
Dog d = new Dog();
d.Woof(); // OK
object o = new Dog();
o.Woof(); // COMPILER ERROR
अंतिम पंक्ति एक संकलक त्रुटि क्योंकि यह स्थिर टाइपिंग अनुबंध का उल्लंघन करती कारण बनता है: आप संकलक कि o
System.Object
से पाने के लिए कुछ भी किया जा सकता है कहा था, लेकिन ऐसा नहीं है कि चीजों से पाने के सभी एक विधि Woof
है। तो संकलक यह कहकर आपकी रक्षा करने की कोशिश कर रहा है कि "आप वहां क्या कर रहे हैं? मैं साबित नहीं कर सकता कि o
में जो कुछ भी है, वह हो सकता है! अगर यह Cat
था?"।
नोट्स:
यह ¹ मतलब यह नहीं है कि हर वस्तु है कि जादुई जानता है कि यह क्या सभी भाषाओं में "है।" कुछ मामलों में (उदा।सी ++ में) किसी ऑब्जेक्ट को बनाते समय यह जानकारी उपयोग की जा सकती है, लेकिन फिर संकलक को कोड को अनुकूलित करने की अधिक स्वतंत्रता को अनुमति देने के लिए "भूल गया" है। यदि ऐसा होता है तो ऑब्जेक्ट अभी भी कुछ है, लेकिन आप इसे पोक नहीं कर सकते हैं और पूछ सकते हैं "आप क्या हैं?"।
² असल में, इस छोटे उदाहरण में यह साबित कर सकता है। लेकिन यह इस ज्ञान का उपयोग नहीं करना चुनेगा क्योंकि स्थिर प्रकार के अनुबंध का सम्मान पूरे बिंदु है।
मुझे मिली इस की सुंदरता यह है कि कभी-कभी, एक विधि को 'कुत्ते' से अधिक के साथ काम करने की आवश्यकता हो सकती है। 'ऑब्जेक्ट ए = नया कुत्ता()' कथन के साथ, आप इसे एक विधि में उपयोग कर सकते हैं। इसी तरह, आप 'ऑब्जेक्ट बी = नई बिल्ली()' कर सकते हैं, और आप उसी तरह इसका उपयोग कर सकते हैं। –
@ केन फिर इंटरफ़ेस का उपयोग क्यों नहीं करते? हाउसपेट की तरह एक = नया कुत्ता(); हाउसपेट इंटरफ़ेस या एक एनिम इंटरफ़ेस में साझा विधियां डालना। – Andy
यह एक डुप्लिकेट होना है ... – slugster