வணக்கம்! கடந்த பாடத்தில், பழமையான வகைகளை வார்ப்பது பற்றி விவாதித்தோம். விவாதிக்கப்பட்டதை சுருக்கமாக நினைவு கூர்வோம்.
பழமையான வகைகளை (இந்த விஷயத்தில், எண் வகைகள்) கூடு கட்டும் பொம்மைகளாக கற்பனை செய்தோம், அவை ஆக்கிரமித்துள்ள நினைவகத்தின் அளவைப் பொறுத்து அளவு மாறுபடும். நீங்கள் நினைவில் வைத்திருப்பது போல், ஒரு பெரிய பொம்மைக்குள் சிறிய பொம்மையை வைப்பது நிஜ வாழ்க்கையிலும் ஜாவா நிரலாக்கத்திலும் எளிமையானது.
மற்றொரு சுவாரஸ்யமான உதாரணத்தைக் கவனியுங்கள்:

public class Main {
public static void main(String[] args) {
int bigNumber = 10000000;
short smallNumber = (short) bigNumber;
System.out.println(smallNumber);
}
}
இது தானியங்கி மாற்றம் அல்லது விரிவுபடுத்துதலுக்கு ஒரு எடுத்துக்காட்டு . இது தானாகவே நடக்கும், எனவே நீங்கள் கூடுதல் குறியீட்டை எழுத வேண்டியதில்லை. இறுதியில், நாங்கள் அசாதாரணமான எதையும் செய்யவில்லை: நாங்கள் ஒரு சிறிய பொம்மையை ஒரு பெரிய பொம்மைக்குள் வைக்கிறோம். அதற்கு நேர்மாறாக ஒரு பெரிய ரஷ்ய பொம்மையை சிறிய பொம்மையாக வைக்க முயற்சித்தால் அது வேறு விஷயம். நிஜ வாழ்க்கையில் நீங்கள் அதைச் செய்ய முடியாது, ஆனால் நிரலாக்கத்தில் உங்களால் முடியும். ஆனால் ஒரு நுணுக்கம் உள்ளது. int
நாம் ஒரு மாறியை வைக்க முயற்சித்தால் short
, விஷயங்கள் நமக்கு அவ்வளவு சீராக நடக்காது. எல்லாவற்றிற்கும் மேலாக, short
மாறி 16 பிட் தகவல்களை மட்டுமே கொண்டுள்ளது, ஆனால் ஒரு int
32 பிட்களை ஆக்கிரமித்துள்ளது! இதன் விளைவாக, அனுப்பப்பட்ட மதிப்பு சிதைந்துவிடும். கம்பைலர் எங்களுக்கு ஒரு பிழையைக் கொடுக்கும் (' நண்பரே, நீங்கள் சந்தேகத்திற்குரிய ஒன்றைச் செய்கிறீர்கள்!'). ஆனால் நாம் நமது மதிப்பை மாற்றும் வகையை வெளிப்படையாகக் குறிப்பிட்டால், அது மேலே சென்று செயல்பாட்டைச் செய்யும்.
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
வகுப்பின் 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
, இது பரம்பரை மரத்தில் குறைவாக உள்ளது. வெளிப்படையான அறிகுறி இல்லாமல், கம்பைலர் அத்தகைய செயல்பாட்டை அனுமதிக்காது, ஆனால் அடைப்புக்குறிக்குள் வகையைக் குறிப்பிட்டால், எல்லாம் வேலை செய்யும். 
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: Pet Errorக்கு விலங்கை அனுப்ப முடியாது ! இந்த நேரத்தில் கம்பைலர் எங்களைக் கத்தவில்லை, ஆனால் நாங்கள் விதிவிலக்காக முடித்தோம். அதற்கான காரணத்தை நாங்கள் ஏற்கனவே அறிவோம்: ஒரு மூலப் பொருளை சந்ததிக் குறிப்புக்கு ஒதுக்க முயற்சிக்கிறோம். ஆனால் அதை ஏன் சரியாக செய்ய முடியாது? ஏனெனில் அனைத்து விலங்குகளும் வீட்டு விலங்குகள் அல்ல. நீங்கள் ஒரு 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();
சந்ததி மாறிக்கு மூதாதையர் பொருளை ஒதுக்க முடியாது. நீங்கள் எதிர் செய்ய முடியும்.
GO TO FULL VERSION