CodeGym /Java Blog /अनियमित /संदर्भ प्रकारों का विस्तार और संकुचन
John Squirrels
स्तर 41
San Francisco

संदर्भ प्रकारों का विस्तार और संकुचन

अनियमित ग्रुप में प्रकाशित
नमस्ते! पिछले पाठ में, हमने प्रिमिटिव टाइप्स को कास्ट करने पर चर्चा की थी। आइए संक्षेप में याद करें कि क्या चर्चा हुई थी। संदर्भ प्रकारों का विस्तार और संकुचन - 1हमने आदिम प्रकारों की कल्पना की (इस मामले में, संख्यात्मक प्रकार) नेस्टिंग गुड़िया के रूप में जो स्मृति की मात्रा के अनुसार आकार में भिन्न होती है। जैसा कि आपको याद होगा, एक छोटी गुड़िया को एक बड़ी गुड़िया के अंदर रखना वास्तविक जीवन और जावा प्रोग्रामिंग दोनों में सरल है।

public class Main {
   public static void main(String[] args) {
       int bigNumber = 10000000;
       short smallNumber = (short) bigNumber;
       System.out.println(smallNumber);
   }
}
यह स्वत: रूपांतरण या प्रसार का एक उदाहरण है । यह अपने आप होता है, इसलिए आपको अतिरिक्त कोड लिखने की आवश्यकता नहीं है। अंत में, हम कुछ भी असामान्य नहीं कर रहे हैं: हम बस एक छोटी गुड़िया को एक बड़ी गुड़िया में डाल रहे हैं। यह एक और बात है अगर हम इसके विपरीत करने की कोशिश करते हैं और एक बड़ी रूसी गुड़िया को एक छोटी गुड़िया में डालते हैं। आप वास्तविक जीवन में ऐसा नहीं कर सकते, लेकिन प्रोग्रामिंग में आप कर सकते हैं। लेकिन एक अति सूक्ष्म अंतर है। अगर हम a को intएक वेरिएबल में डालने की कोशिश करते हैं short, तो चीजें हमारे लिए इतनी आसानी से नहीं चलती हैं। आखिरकार, shortचर केवल 16 बिट्स की जानकारी रखता है, लेकिन int32 बिट्स पर कब्जा कर लेता है! नतीजतन, पारित मूल्य विकृत है। संकलक हमें एक त्रुटि देगा (' यार, तुम कुछ संदिग्ध कर रहे हो!')। लेकिन अगर हम स्पष्ट रूप से उस प्रकार को इंगित करते हैं जिसे हम अपना मूल्य परिवर्तित कर रहे हैं, तो यह आगे बढ़ेगा और ऑपरेशन करेगा।

public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       bigNumber = (short) bigNumber;

       System.out.println(bigNumber);

   }

}
ठीक यही हमने ऊपर के उदाहरण में किया। ऑपरेशन किया गया था, लेकिन क्योंकि shortचर 32 बाइट्स में से केवल 16 को समायोजित कर सकता है, अंतिम मान विकृत है और हमें संख्या -27008 मिलती है । इस तरह के ऑपरेशन को एक स्पष्ट रूपांतरण या संकीर्ण कहा जाता है ।

संदर्भ प्रकारों के विस्तार और संकुचन के उदाहरण

अब उन्हीं ऑपरेटरों के बारे में बात करते हैं जो आदिम प्रकारों पर नहीं, बल्कि वस्तुओं और संदर्भ चर पर लागू होते हैं ! यह जावा में कैसे काम करता है? यह वास्तव में काफी सरल है। ऐसी वस्तुएं हैं जो असंबंधित हैं। यह मान लेना तर्कसंगत होगा कि उन्हें एक दूसरे में परिवर्तित नहीं किया जा सकता है, न तो स्पष्ट रूप से और न ही स्वचालित रूप से:

public class Cat {
}

public class Dog {
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Dog(); // Error!

   }

}
यहाँ, निश्चित रूप से, हमें एक त्रुटि मिलती है। और कक्षाएं एक दूसरे से संबंधित नहीं हैं, और हमने एक से दूसरे Catमें Dogजाने के लिए 'कनवर्टर' नहीं लिखा है। यह समझ में आता है कि हम ऐसा नहीं कर सकते: संकलक को पता नहीं है कि इन वस्तुओं को एक प्रकार से दूसरे में कैसे परिवर्तित किया जाए। यदि वस्तुएं संबंधित हैं, ठीक है, यह दूसरी बात है! संबंधित कैसे? इन सबसे ऊपर, विरासत के माध्यम से। आइए कक्षाओं की एक छोटी प्रणाली बनाने के लिए वंशानुक्रम का उपयोग करने का प्रयास करें। जानवरों का प्रतिनिधित्व करने के लिए हमारे पास एक सामान्य वर्ग होगा:

public class Animal {

   public void introduce() {

       System.out.println("I'm Animal");
   }
}
हर कोई जानता है कि जानवरों को पालतू (पालतू जानवर) या जंगली बनाया जा सकता है:

public class WildAnimal extends Animal {

   public void introduce() {

       System.out.println("I'm WildAnimal");
   }
}

public class Pet extends Animal {

   public void introduce() {

       System.out.println("I'm Pet");
   }
}
उदाहरण के लिए, केनाइन लें - हमारे पास घरेलू कुत्ते और कोयोट हैं:

public class Dog extends Pet {

   public void introduce() {

       System.out.println("I'm Dog");
   }
}



public class Coyote extends WildAnimal {

   public void introduce() {

       System.out.println ("I'm Coyote");
   }
}
हमने उन्हें समझने में आसान बनाने के लिए विशेष रूप से सबसे बुनियादी कक्षाओं को चुना है। हमें वास्तव में किसी भी क्षेत्र की आवश्यकता नहीं है, और एक विधि ही काफी है। आइए इस कोड को निष्पादित करने का प्रयास करें:

public class Main {

   public static void main(String[] args) {

       Animal animal = new Pet();
       animal.introduce();
   }
}
आपको क्या लगता है कंसोल पर प्रदर्शित किया जाएगा? क्या कक्षा या कक्षा introduceकी विधि लागू की जाएगी? पढ़ना जारी रखने से पहले अपने उत्तर को सही ठहराने का प्रयास करें। और यहाँ परिणाम है! मैं पालतू हूँ हमें वह क्यों मिला? यह सब सरल है। हमारे पास एक मूल चर और एक वंशज वस्तु है। लेखन से, PetAnimal

Animal animal = new Pet();
हमने एक Petसंदर्भ को चौड़ा किया और इसे एक Animalचर के लिए नियत किया। आदिम प्रकारों के साथ, जावा में संदर्भ प्रकार स्वचालित रूप से विस्तृत हो जाते हैं। ऐसा करने के लिए आपको अतिरिक्त कोड लिखने की आवश्यकता नहीं है। अब हमारे पास पैरेंट रेफरेंस को असाइन की गई डिसेंडेंट ऑब्जेक्ट है। नतीजतन, हम देखते हैं कि वंश वर्ग पर विधि कॉल किया जाता है। यदि आप अभी भी पूरी तरह से नहीं समझ पाए हैं कि यह कोड क्यों काम करता है, तो इसे सरल भाषा में फिर से लिखें:

Animal animal = new DomesticatedAnimal();
इसमें कोई समस्या नहीं है, है ना? कल्पना कीजिए कि यह वास्तविक जीवन है, और संदर्भ केवल एक कागज़ का लेबल है जिस पर 'पशु' लिखा हुआ है। यदि आप उस कागज़ के टुकड़े को लेकर किसी पालतू जानवर के कॉलर से जोड़ दें, तो सब कुछ सही हो जाएगा। आखिर कोई भी पालतू जानवर है! विपरीत प्रक्रिया - वंशानुक्रम वृक्ष को वंशजों तक ले जाना - संकुचित हो रहा है:

public class Main {

   public static void main(String[] args) {

       WildAnimal wildAnimal = new Coyote();

       Coyote coyote = (Coyote) wildAnimal;

       coyote.introduce();
   }
}
जैसा कि आप देख सकते हैं, यहाँ हम स्पष्ट रूप से उस वर्ग को इंगित करते हैं जिसे हम अपनी वस्तु में बदलना चाहते हैं। हमारे पास पहले एक WildAnimalवेरिएबल था, और अब हमारे पास एक है Coyote, जो इनहेरिटेंस ट्री पर नीचे है। यह समझ में आता है कि एक स्पष्ट संकेत के बिना कंपाइलर इस तरह के ऑपरेशन की अनुमति नहीं देगा, लेकिन अगर हम टाइप को कोष्ठक में इंगित करते हैं, तो सब कुछ काम करता है। संदर्भ प्रकारों का विस्तार और संकुचन - 2एक और दिलचस्प उदाहरण पर विचार करें:

public class Main {

   public static void main(String[] args) {

       Pet pet = new Animal(); // Error!
   }
}
संकलक एक त्रुटि उत्पन्न करता है! लेकिन क्यों? क्योंकि आप एक मूल वस्तु को वंशज संदर्भ में निर्दिष्ट करने का प्रयास कर रहे हैं। दूसरे शब्दों में, आप ऐसा कुछ करने की कोशिश कर रहे हैं:

DomesticatedAnimal domesticatedAnimal = new Animal();
ठीक है, शायद सब कुछ काम करेगा अगर हम स्पष्ट रूप से उस प्रकार को निर्दिष्ट करते हैं जिसे हम बदलने की कोशिश कर रहे हैं? इसने संख्याओं के साथ काम किया — आइए इसे आजमाएँ! :)

public class Main {

   public static void main(String[] args) {

       Pet pet = (Pet) new Animal();
   }
}
धागे में अपवाद "मुख्य" java.lang.ClassCastException: पशु को पालतू त्रुटि में नहीं डाला जा सकता! कंपाइलर इस बार हम पर चिल्लाया नहीं, लेकिन हम एक अपवाद के साथ समाप्त हो गए। हम पहले से ही इसका कारण जानते हैं: हम एक मूल वस्तु को वंशज संदर्भ में निर्दिष्ट करने का प्रयास कर रहे हैं। लेकिन आप वास्तव में ऐसा क्यों नहीं कर सकते? क्योंकि सभी जानवर पालतू जानवर नहीं होते। आपने एक Animalऑब्जेक्ट बनाया है और इसे एक Petवेरिएबल पर असाइन करने का प्रयास कर रहे हैं। एक कोयोट भी एक है Animal, लेकिन यह एक नहीं है Pet। दूसरे शब्दों में, जब आप लिखते हैं

Pet pet = (Pet) new Animal();
new Animal()किसी भी जानवर का प्रतिनिधित्व कर सकता है, जरूरी नहीं कि वह पालतू हो! स्वाभाविक रूप से, आपका Pet petचर केवल पालतू जानवरों (और उनके वंशजों) को संग्रहित करने के लिए उपयुक्त है, किसी भी प्रकार के जानवर के लिए नहीं। यही कारण है कि एक विशेष जावा अपवाद, ClassCastExceptionउन मामलों के लिए बनाया गया था जहां कक्षाएं कास्टिंग करते समय त्रुटि होती है। चीजों को स्पष्ट करने के लिए आइए इसकी फिर से समीक्षा करें। एक मूल संदर्भ वंश वर्ग के उदाहरणों को इंगित कर सकता है:

public class Main {

   public static void main(String[] args) {

       Pet pet = new Pet();
       Animal animal = pet;

       Pet pet2 = (Pet) animal;
       pet2.introduce();
   }
}
उदाहरण के लिए, यहाँ हमें कोई समस्या नहीं है। हमारे पास एक चर Petद्वारा संदर्भित वस्तु है। Petबाद में, एक Animalसंदर्भ ने उसी वस्तु की ओर इशारा किया। उसके बाद, हम animalएक में कनवर्ट करते हैं Pet। वैसे, यह हमारे लिए क्यों काम करता है? पिछली बार हमें एक अपवाद मिला था! क्योंकि इस बार हमारी मूल वस्तु है Pet!

Pet pet = new Pet();
लेकिन पिछले उदाहरण में, यह एक Animalवस्तु थी:

Pet pet = (Pet) new Animal();
आप एक पूर्वज वस्तु को एक वंशज चर के लिए निर्दिष्ट नहीं कर सकते। आप इसके विपरीत कर सकते हैं।
टिप्पणियां
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION