CodeGym /Java Blog /यादृच्छिक /संदर्भ प्रकारांचे रुंदीकरण आणि संकुचित करणे
John Squirrels
पातळी 41
San Francisco

संदर्भ प्रकारांचे रुंदीकरण आणि संकुचित करणे

यादृच्छिक या ग्रुपमध्ये प्रकाशित केले
हाय! मागील धड्यात, आम्ही कास्टिंग आदिम प्रकारांवर चर्चा केली. काय चर्चा झाली ते थोडक्यात आठवूया. संदर्भ प्रकारांचे रुंदीकरण आणि अरुंदीकरण - १आम्ही आदिम प्रकारांची कल्पना केली (या प्रकरणात, संख्यात्मक प्रकार) घरट्याच्या बाहुल्या ज्यांचा आकार त्यांच्या व्यापलेल्या मेमरीनुसार बदलतो. तुम्हाला आठवत असेल की, मोठ्या बाहुलीमध्ये लहान बाहुली ठेवणे वास्तविक जीवनात आणि जावा प्रोग्रामिंगमध्ये सोपे आहे.

public class Main {
   public static void main(String[] args) {
       int bigNumber = 10000000;
       short smallNumber = (short) bigNumber;
       System.out.println(smallNumber);
   }
}
हे स्वयंचलित रूपांतरण किंवा रुंदीकरणाचे उदाहरण आहे . हे स्वतःच घडते, म्हणून आपल्याला अतिरिक्त कोड लिहिण्याची आवश्यकता नाही. सरतेशेवटी, आम्ही काहीही असामान्य करत नाही: आम्ही फक्त एक लहान बाहुली एका मोठ्या बाहुलीमध्ये ठेवत आहोत. जर आपण उलट करण्याचा प्रयत्न केला आणि एक मोठी रशियन बाहुली लहान बाहुलीमध्ये ठेवली तर ही दुसरी बाब आहे. तुम्ही ते वास्तविक जीवनात करू शकत नाही, परंतु प्रोग्रामिंगमध्ये तुम्ही करू शकता. पण एक बारकावे आहे. 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 क्रमांक मिळेल . अशा ऑपरेशनला स्पष्ट रूपांतरण किंवा अरुंद करणे म्हणतात .

संदर्भ प्रकारांचे रुंदीकरण आणि अरुंदीकरणाची उदाहरणे

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

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वर्गाची पद्धत Petकिंवा Animalवर्ग मागवला जाईल का ? वाचन सुरू ठेवण्यापूर्वी तुमच्या उत्तराचे समर्थन करण्याचा प्रयत्न करा. आणि येथे परिणाम आहे! मी पेट आहे आम्हाला ते का मिळाले? हे सर्व सोपे आहे. आमच्याकडे पॅरेंट व्हेरिएबल आणि डिसेंडंट ऑब्जेक्ट आहे. लिहून,

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क्लास कास्ट करताना एरर उद्भवलेल्या प्रकरणांसाठी विशेष Java अपवाद, , तयार केला गेला. गोष्टी अधिक स्पष्ट करण्यासाठी त्याचे पुन्हा पुनरावलोकन करूया. पालक संदर्भ वंशज वर्गाच्या उदाहरणांकडे निर्देश करू शकतात:

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संदर्भाने त्याच वस्तूकडे निर्देश केला. त्यानंतर, आम्ही animala मध्ये रूपांतरित करतो 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