"नमस्ते, अमीगो! आज के पाठ का विषय प्रकार रूपांतरणों को चौड़ा करना और संकुचित करना है। आपने आदिम प्रकारों को चौड़ा करने और संकीर्ण करने के बारे में बहुत पहले सीखा था। स्तर 10 पर। आज हम बात करने जा रहे हैं कि यह संदर्भ प्रकारों के लिए कैसे काम करता है, अर्थात कक्षाओं के उदाहरण।"

वास्तव में, यह सब काफी सरल है। एक वर्ग की वंशानुक्रम श्रृंखला की कल्पना करें: वर्ग, उसके माता-पिता, माता-पिता के माता-पिता, आदि, सभी तरह से ऑब्जेक्ट क्लास में। क्योंकि एक वर्ग में उस वर्ग के सभी सदस्य तरीके शामिल होते हैं जो इसे विरासत में मिलते हैं , वर्ग का एक उदाहरण एक चर में सहेजा जा सकता है जिसका प्रकार उसके माता-पिता में से कोई है।

यहाँ एक उदाहरण है:

कोड विवरण
class Animal
{
public void doAnimalActions();
}class Cat extends Animal
{
public void doCatActions();
}class Tiger extends Cat
{
public void doTigerActions();
}
यहाँ हमारे पास तीन वर्ग घोषणाएँ हैं: पशु, बिल्ली और बाघ। बिल्ली को पशु विरासत में मिला है। और टाइगर को कैट विरासत में मिली।
public static void main(String[] args)
{
Tiger tiger = new Tiger();
Cat cat = new Tiger();
Animal animal = new Tiger();
Object obj = new Tiger();
}
एक टाइगर ऑब्जेक्ट को हमेशा एक वेरिएबल को सौंपा जा सकता है जिसका प्रकार उसके पूर्वजों में से एक है। बाघ वर्ग के लिए, ये कैट, एनिमल और ऑब्जेक्ट हैं।

आइए अब रूपांतरणों के विस्तार और संकुचन पर एक नज़र डालें।

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

वंशानुक्रम श्रृंखला को ऊपर ले जाने को चौड़ा करना कहा जाता है, क्योंकि यह अधिक सामान्य प्रकार की ओर ले जाता है। हालाँकि, ऐसा करने में हम वंशानुक्रम के माध्यम से कक्षा में जोड़े गए तरीकों को लागू करने की क्षमता खो देते हैं।

कोड विवरण
public static void main(String[] args)
{
Object obj = new Tiger();
Animal animal = (Animal) obj;
Cat cat = (Cat) obj;
Tiger tiger = (Tiger) animal;
Tiger tiger2 = (Tiger) cat;
}
प्रकार को संकीर्ण करते समय, आपको एक प्रकार के रूपांतरण ऑपरेटर का उपयोग करने की आवश्यकता होती है, अर्थात हम एक स्पष्ट रूपांतरण करते हैं।

यह जावा मशीन को यह जांचने का कारण बनता है कि क्या वस्तु वास्तव में उस प्रकार को प्राप्त करती है जिसे हम इसे बदलना चाहते हैं।

इस छोटे से नवाचार ने टाइप कास्टिंग त्रुटियों की संख्या में कई गुना कमी की और जावा प्रोग्राम की स्थिरता में काफी वृद्धि की।

कोड विवरण
public static void main(String[] args)
{
Object obj = new Tiger();
if (obj instanceof Cat)
{
Cat cat = (Cat) obj;
cat.doCatActions();
}}
बेहतर अभी तक, एक  उदाहरण चेक का उपयोग करें
public static void main(String[] args)
{
Animal animal = new Tiger();
doAllAction(animal);

Animal animal2 = new Cat();
doAllAction(animal2);

Animal animal3 = new Animal();
doAllAction(animal3);
}

public static void doAllAction(Animal animal)
{
if (animal instanceof Tiger)
{
Tiger tiger = (Tiger) animal;
tiger.doTigerActions();
}

if (animal instanceof Cat)
{
Cat cat = (Cat) animal;
cat.doCatActions();
}

animal.doAnimalActions();
}
और यहाँ क्यों है। बाईं ओर के उदाहरण पर एक नज़र डालें।

हम (हमारा कोड) हमेशा नहीं जानते कि हम किस प्रकार की वस्तु के साथ काम कर रहे हैं। यह चर (पशु) या किसी वंशज प्रकार (बिल्ली, बाघ) के समान प्रकार की वस्तु हो सकती है।

DoAllAction पद्धति पर विचार करें। ऑब्जेक्ट के प्रकार के पारित होने के बावजूद यह सही ढंग से काम करता है।

दूसरे शब्दों में, यह तीनों प्रकारों के लिए सही ढंग से काम करता है: पशु, बिल्ली और बाघ।

public static void main(String[] args)
{
Cat cat = new Tiger();
Animal animal = cat;
Object obj = cat;
}
यहां हमारे पास तीन असाइनमेंट ऑपरेशंस हैं। ये सभी व्यापक रूपांतरण के उदाहरण हैं।

यहां टाइप कास्ट ऑपरेटर की जरूरत नहीं है, क्योंकि किसी चेक की जरूरत नहीं है। एक वस्तु संदर्भ हमेशा एक चर में संग्रहीत किया जा सकता है जिसका प्रकार उसके पूर्वजों में से एक है।

"ओह, दूसरे से अंतिम उदाहरण ने सब कुछ स्पष्ट कर दिया: चेक की आवश्यकता क्यों है, और टाइप कास्टिंग की आवश्यकता क्यों है।"

"मुझे आशा है। मैं इस तथ्य पर आपका ध्यान आकर्षित करना चाहता हूं:"

इनमें से कोई भी किसी वस्तु को किसी भी तरह से बदलने का कारण नहीं बनता है! केवल एक चीज जो बदलती है वह है किसी विशेष संदर्भ चर पर कॉल करने के लिए उपलब्ध विधियों की संख्या ।

उदाहरण के लिए, एक कैट चर आपको doAnimalActions और doCatActions विधियों को कॉल करने देता है। यह doTigerActions विधि के बारे में कुछ भी नहीं जानता, भले ही यह टाइगर ऑब्जेक्ट की ओर इशारा करता हो।

"हाँ, मैं समझ गया। यह जितना मैंने सोचा था उससे कहीं अधिक आसान था।"