1. टाइपकास्टिंग

संदर्भ प्रकार (वर्ग) संचयित करणारे चल देखील भिन्न प्रकारांमध्ये रूपांतरित केले जाऊ शकतात. परंतु हे केवळ एकाच प्रकारच्या पदानुक्रमात कार्य करते. एक साधे उदाहरण पाहू. समजा आपल्याकडे खालील वर्ग श्रेणीक्रम आहे, ज्यामध्ये खालील वर्ग वरील वर्गांचे वारसा घेतात.

टाइपकास्टिंग

संदर्भ प्रकार तसेच आदिम प्रकारांचे टाइपकास्टिंग देखील एकतर रुंदीकरण आणि अरुंद म्हणून वर्गीकृत केले आहे.

आपण पाहतो की मांजर वर्गाला पाळीव प्राणी वर्गाचा वारसा मिळतो आणि पाळीव प्राणी वर्गाला, पशु वर्गाचा वारसा मिळतो.

जर आपण असा कोड लिहिला तर:

Animal kitten = new Cat();

हे एक रुंदीकरण प्रकार रूपांतरण आहे . त्याला अव्यक्त कास्ट असेही म्हणतात. आम्ही मांजरीचा संदर्भ विस्तृत केला आहे जेणेकरून तो आता मांजरीच्या वस्तूचा संदर्भ देईल. अशा प्रकारच्या रूपांतरणासह, आम्ही मांजरीच्या वर्गात उपस्थित असलेल्या परंतु प्राणी वर्गात अनुपस्थित असलेल्या कॉल पद्धतींसाठी मांजरीचे पिल्लू संदर्भ वापरू शकणार नाही .

एक संकुचित रूपांतरण (किंवा स्पष्ट कास्ट) उलट दिशेने होते:

Cat cat = (Cat) kitten;

आम्ही स्पष्टपणे सूचित केले आहे की आम्हाला मांजरीच्या व्हेरिएबलमध्ये (ज्याचा प्रकार प्राणी आहे ) संग्रहित संदर्भ मांजरीच्या प्रकारात टाकायचा आहे.



2. ऑब्जेक्टचा प्रकार तपासत आहे

परंतु येथे आपल्याला खूप सावधगिरी बाळगण्याची आवश्यकता आहे. आपण हे केल्यास:

Animal beast = new Cat();
Wolf grayWolf = (Wolf) beast;

कंपाइलर या कोडला अनुमती देईल, परंतु जेव्हा प्रोग्राम चालेल तेव्हा एक त्रुटी असेल ! JVM अपवाद करेल:

Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf

मांजरीच्या वस्तूचे संदर्भ फक्त व्हेरिएबल्समध्ये संग्रहित केले जाऊ शकतात ज्यांचा प्रकार मांजर वर्गाचा पूर्वज आहे: पाळीव प्राणी, प्राणी किंवा ऑब्जेक्ट.

अस का?

येथे संबंधित मुद्दा असा आहे की ऑब्जेक्टचा संदर्भ त्या ऑब्जेक्टच्या पद्धती आणि व्हेरिएबल्सचा संदर्भ देण्यासाठी वापरला जातो . आणि जर आपण एखाद्या मांजरीच्या ऑब्जेक्टचा संदर्भ संग्रहित करण्यासाठी अॅनिमल व्हेरिएबलचा वापर केला तर कोणतीही अडचण येणार नाही: मांजरीच्या प्रकारात नेहमीच अॅनिमल प्रकाराचे व्हेरिएबल्स आणि पद्धती असतात - ते त्यांना वारशाने मिळालेले असतात!

परंतु जर JVM ने आम्हाला वुल्फ व्हेरिएबलमध्ये कॅट ऑब्जेक्टचा संदर्भ संग्रहित करण्याची परवानगी दिली, तर त्या व्हेरिएबलमध्ये संग्रहित कॅट ऑब्जेक्टमध्ये अस्तित्वात नसलेली पद्धत कॉल करण्यासाठी आम्ही ग्रेवुल्फ व्हेरिएबल वापरण्याचा प्रयत्न करू शकतो. . त्यामुळे या व्यवस्थेला परवानगी नाही.

Java मध्ये एक विशेष instanceofऑपरेटर आहे जो तुम्हाला एखादी वस्तू विशिष्ट प्रकारची आहे की नाही हे तपासू देतो आणि म्हणून ती विशिष्ट प्रकारच्या व्हेरिएबलमध्ये संग्रहित केली जाऊ शकते. हे अगदी सोपे दिसते:

variable instanceof Type

उदाहरण:

Animal beast = new Cat();
if (beast instanceof Wolf)
{
   Wolf grayWolf = (Wolf) beast;
}

या कोडमुळे एरर होणार नाहीत — अगदी रनटाइमच्या वेळीही.

परिस्थिती स्पष्ट करणारी आणखी काही उदाहरणे येथे आहेत:

रुंदीकरण प्रकार रूपांतरण वर्णन
Cow cow = new Whale();

हे एक क्लासिक रुंदीकरण रूपांतरण आहे — कोणत्याही प्रकारच्या रूपांतरण ऑपरेटरची आवश्यकता नाही. आता फक्त क्लासमध्ये परिभाषित केलेल्या पद्धती Cowऑब्जेक्टवर कॉल केल्या जाऊ शकतात Whale.

व्हेरिएबलवर , cowकंपाइलर तुम्हाला फक्त त्याच्या प्रकारात (वर्ग) असलेल्या पद्धती कॉल करू देतो Cow.

संकुचित प्रकार रूपांतरण
Cow cow = new Whale();
if (cow instanceof Whale)
{
   Whale whale = (Whale) cow;
}
क्लासिक संकुचित रूपांतरण: तुम्हाला टाइप चेक आणि कास्ट ऑपरेटर जोडण्याची आवश्यकता आहे.
व्हेरिएबल Cow cowऑब्जेक्टचा संदर्भ संग्रहित करते Whale.
आम्ही हे प्रकरण असल्याची पडताळणी करतो आणि नंतर (संकुचित) प्रकार रूपांतरण करतो. किंवा त्याला असेही म्हणतात:
एक प्रकारचा कास्ट
.

Cow cow = new Cow();
Whale whale = (Whale) cow; // Exception
तुम्ही ऑब्जेक्टचा प्रकार न तपासता संदर्भ प्रकार कमी करू शकता.
जर cowव्हेरिएबल एखाद्या ऑब्जेक्टचा संदर्भ देत असेल जो a नाही Whale, तर एक InvalidClassCastExceptionव्युत्पन्न होईल.


3. मूळ पद्धत कॉल करणे: superकीवर्ड

पालक वर्गाची पद्धत ओव्हरराइड करताना, काहीवेळा ती आमच्या स्वतःच्या पद्धतीने बदलण्याऐवजी, आम्ही फक्त त्यास थोडेसे पूरक करू इच्छितो.

आम्ही आमच्या पद्धतीमध्ये पालक वर्गाची पद्धत आणि नंतर आमच्या स्वत: च्या काही कोड कार्यान्वित करू शकलो तर ते छान होईल. किंवा कदाचित प्रथम आमचा स्वतःचा कोड कार्यान्वित करा आणि नंतर पालक वर्गाच्या पद्धतीला कॉल करा.

आणि जावा आम्हाला तेच करू देते. पालक वर्गाची पद्धत कॉल करण्यासाठी, हे करा:

super.method(arguments);

उदाहरणे:

class PeaceTime
{
   public double getPi()
   {
      return 3.14;
   }
}

class WarTime extends PeaceTime
{
   public double getPi()
   {
      return super.getPi()*2;  // 3.14*2
   }
}

युद्धकाळात, चे मूल्य Pi6 पेक्षा जास्त असू शकते! अर्थात, आम्ही विनोद करत आहोत, परंतु हे सर्व कसे कार्य करू शकते हे हे उदाहरण दाखवते.

गोष्टी थोड्या स्पष्ट करण्यासाठी येथे आणखी काही उदाहरणे आहेत:

कोड वर्णन
class Cow
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a cow");
   }
}

class Whale extends Cow
{
   public void printName()
   {
      System.out.print("This is incorrect: ");
      super.printName();
      System.out.println("I'm a whale");
   }
}
Cowआणि Whaleवर्ग
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printAll();
}
स्क्रीन आउटपुट असेल:
I'm a white whale
This is incorrect: I'm a cow
I'm a whale

ही कठीण गोष्ट आहे. प्रामाणिकपणे, ही OOP मधील सर्वात कठीण गोष्टींपैकी एक आहे . ते म्हणाले, तुम्हाला ते जाणून घेणे आणि समजून घेणे आवश्यक आहे.