வணக்கம்! இன்று நாம் ஒரு முக்கியமான வழிமுறையைப் பார்ப்போம்: உள்ளமை வகுப்புகளில் பரம்பரை. நீங்கள் ஒரு உள்ளமைக்கப்பட்ட வகுப்பை வேறு சில வகுப்பைப் பெறச் செய்ய வேண்டுமானால் நீங்கள் என்ன செய்வீர்கள் என்பதைப் பற்றி நீங்கள் எப்போதாவது யோசித்திருக்கிறீர்களா? இல்லையென்றால், என்னை நம்புங்கள்: இந்த சூழ்நிலை குழப்பமாக இருக்கலாம், ஏனென்றால் நிறைய நுணுக்கங்கள் உள்ளன.
- உள்ளமைக்கப்பட்ட வகுப்பை சில வகுப்பைப் பெறுகிறோமா? அல்லது சில வகுப்பினரை உள்ளமைக்கப்பட்ட வகுப்பாக மாற்றுகிறோமா?
- குழந்தை/பெற்றோர் வர்க்கம் சாதாரண பொது வகுப்பா, அல்லது அதுவும் உள்ளமைக்கப்பட்ட வகுப்பா?
- இறுதியாக, இந்த எல்லா சூழ்நிலைகளிலும் நாம் எந்த வகையான உள்ளமைக்கப்பட்ட வகுப்புகளைப் பயன்படுத்துகிறோம்?
நிலையான உள்ளமை வகுப்புகள்
அவர்களின் பரம்பரை விதிகள் எளிமையானவை. இங்கே நீங்கள் உங்கள் இதயம் விரும்பும் எதையும் செய்யலாம். ஒரு நிலையான உள்ளமை வகுப்பு மரபுரிமை பெறலாம்:- ஒரு சாதாரண வகுப்பு
- வெளிப்புற வகுப்பில் அல்லது அதன் மூதாதையர்களில் அறிவிக்கப்பட்ட ஒரு நிலையான உள்ளமை வகுப்பு
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
Drawing
குறியீட்டை மாற்றி ஒரு நிலையான உள்ளமை வகுப்பையும் அதன் சந்ததியையும் உருவாக்க முயற்சிப்போம் — Boeing737Drawing
.
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
}
public static class Boeing737Drawing extends Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
நீங்கள் பார்க்க முடியும் என, எந்த பிரச்சனையும் இல்லை. நாம் வகுப்பை வெளியே இழுத்து Drawing
, நிலையான உள்ளமைக்கப்பட்ட வகுப்பிற்குப் பதிலாக சாதாரண பொது வகுப்பாக மாற்றலாம் - எதுவும் மாறாது.
public class Drawing {
}
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Boeing737Drawing extends Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
இதை நாங்கள் புரிந்துகொள்கிறோம். ஆனால் எந்த வகுப்புகள் நிலையான உள்ளமைக்கப்பட்ட வகுப்பைப் பெறலாம்? நடைமுறையில் ஏதேனும்! Nested/non-nested, static/non-static — இது ஒரு பொருட்டல்ல. இங்கே நாம் Boeing737Drawing
உள் வகுப்பை Drawing
நிலையான உள்ளமை வகுப்பைப் பெறுகிறோம்:
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
}
public class Boeing737Drawing extends Drawing {
public int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
இது போன்ற ஒரு உதாரணத்தை நீங்கள் உருவாக்கலாம் Boeing737Drawing
:
public class Main {
public static void main(String[] args) {
Boeing737 boeing737 = new Boeing737(1990);
Boeing737.Boeing737Drawing drawing = boeing737.new Boeing737Drawing();
System.out.println(drawing.getMaxPassengersCount());
}
}
எங்கள் Boeing737Drawing
வகுப்பு ஒரு நிலையான வகுப்பைப் பெற்றாலும், அது நிலையானது அல்ல! இதன் விளைவாக, அது எப்போதும் வெளி வர்க்கத்தின் ஒரு உதாரணம் தேவைப்படும். Boeing737Drawing
வகுப்பில் இருந்து வகுப்பை அகற்றி Boeing737
, எளிய பொது வகுப்பாக மாற்றலாம். எதுவும் மாறாது. இது இன்னும் நிலையான உள்ளமை வகுப்பைப் பெறலாம் Drawing
.
public class Boeing737 {
private int manufactureYear;
public static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
}
}
public class Boeing737Drawing extends Boeing737.Drawing {
public int getMaxPassengersCount() {
return Boeing737.maxPassengersCount;
}
ஒரே முக்கியமான விஷயம் என்னவென்றால், இந்த விஷயத்தில் நாம் நிலையான maxPassengersCount
மாறியை பொதுவில் வைக்க வேண்டும். அது தனிப்பட்டதாக இருந்தால், ஒரு சாதாரண பொது வகுப்பினர் அதை அணுக முடியாது. நிலையான வகுப்புகளைக் கண்டுபிடித்துள்ளோம்! :) இப்போது உள் வகுப்புகளுக்கு செல்லலாம். அவை 3 வகைகளில் வருகின்றன: எளிய உள் வகுப்புகள், உள்ளூர் வகுப்புகள் மற்றும் அநாமதேய உள் வகுப்புகள். மீண்டும், எளிமையிலிருந்து சிக்கலான நிலைக்கு செல்லலாம் :)
அநாமதேய உள் வகுப்புகள்
ஒரு அநாமதேய உள் வர்க்கம் மற்றொரு வகுப்பைப் பெற முடியாது. வேறு எந்த வகுப்பினரும் அநாமதேய வகுப்பைப் பெற முடியாது. இது எளிமையானதாக இருக்க முடியாது! :)உள்ளூர் வகுப்புகள்
உள்ளூர் வகுப்புகள் (நீங்கள் மறந்துவிட்டால்) மற்றொரு வகுப்பின் குறியீடு தொகுதிக்குள் அறிவிக்கப்படும். பெரும்பாலும், இது வெளிப்புற வகுப்பின் சில முறைகளுக்குள் நிகழ்கிறது. தர்க்கரீதியாக, அதே முறையில் (அல்லது குறியீடு தொகுதி) உள்ள மற்ற உள்ளூர் வகுப்புகள் மட்டுமே உள்ளூர் வகுப்பைப் பெற முடியும். இங்கே ஒரு உதாரணம்:public class PhoneNumberValidator {
public void validatePhoneNumber(final String number) {
class PhoneNumber {
private String phoneNumber;
public PhoneNumber() {
this.phoneNumber = number;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
class CellPhoneNumber extends PhoneNumber {
}
class LandlinePhoneNumber extends PhoneNumber {
}
// ...number validation code
}
}
இது உள்ளூர் வகுப்புகள் பற்றிய எங்கள் பாடத்தின் குறியீடு. எங்கள் எண் வேலிடேட்டர் வகுப்பில் PhoneNumber
உள்ளூர் வகுப்பு உள்ளது. எடுத்துக்காட்டாக, ஒரு மொபைல் ஃபோன் எண் மற்றும் லேண்ட்லைன் ஃபோன் எண் போன்ற இரண்டு தனித்தனி நிறுவனங்களைப் பிரதிநிதித்துவப்படுத்த இது தேவைப்பட்டால், அதே முறையில் மட்டுமே இதைச் செய்ய முடியும். காரணம் எளிதானது: உள்ளூர் வகுப்பின் நோக்கம் அது அறிவிக்கப்படும் முறைக்கு (குறியீடு தொகுதி) வரையறுக்கப்பட்டுள்ளது. இதன் விளைவாக, எங்களால் அதை வெளிப்புறமாகப் பயன்படுத்த முடியாது (வகுப்பு மரபுரிமை உட்பட). இருப்பினும், உள்ளூர் வகுப்பிற்குள்ளேயே மரபுரிமைக்கான சாத்தியங்கள் மிகவும் பரந்தவை! ஒரு உள்ளூர் வர்க்கம் பெறலாம்:
- ஒரு சாதாரண வகுப்பு.
- உள்ளூர் வகுப்பின் அதே வகுப்பில் அல்லது அதன் மூதாதையர்களில் ஒருவரில் அறிவிக்கப்பட்ட உள் வகுப்பு.
- இதே முறையில் மற்றொரு உள்ளூர் வகுப்பு அறிவிக்கப்பட்டது (குறியீடு தொகுதி).
public class PhoneNumberValidator {
class PhoneNumber {
private String phoneNumber;
public PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
public void validatePhoneNumber(final String number) {
class CellPhoneNumber extends PhoneNumber {
public CellPhoneNumber(String phoneNumber) {
super(number);
}
}
class LandlinePhoneNumber extends PhoneNumber {
public LandlinePhoneNumber(String phoneNumber) {
super(number);
}
}
// ...number validation code
}
}
இங்கே நாங்கள் PhoneNumber
வகுப்பை முறையிலிருந்து அகற்றி validatePhoneNumber()
, உள்ளூர் வகுப்பிற்குப் பதிலாக உள் வகுப்பாக மாற்றினோம். இது எங்களின் 2 உள்ளூர் வகுப்புகளை வாரிசாகப் பெறுவதைத் தடுக்காது. எடுத்துக்காட்டு 2 — "... அல்லது இந்த வகுப்பின் முன்னோர்களில்." இப்போது இது ஏற்கனவே மிகவும் சுவாரஸ்யமானது. PhoneNumber
பரம்பரைச் சங்கிலியில் நாம் இன்னும் மேலே செல்ல முடியும் . ஒரு சுருக்க வகுப்பை அறிவிப்போம் AbstractPhoneNumberValidator
, இது எங்கள் வகுப்பின் மூதாதையராக மாறும் PhoneNumberValidator
:
public abstract class AbstractPhoneNumberValidator {
class PhoneNumber {
private String phoneNumber;
public PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
}
நீங்கள் பார்ப்பது போல், நாங்கள் அதை அறிவிக்கவில்லை - PhoneNumber
உள் வகுப்பையும் அதற்குள் நகர்த்தினோம். இருப்பினும், அதன் வழித்தோன்றலில் PhoneNumberValidator
, முறைகளில் அறிவிக்கப்பட்ட உள்ளூர் வகுப்புகள் PhoneNumber
எந்த பிரச்சனையும் இல்லாமல் மரபுரிமையாக இருக்கும்!
public class PhoneNumberValidator extends AbstractPhoneNumberValidator {
public void validatePhoneNumber(final String number) {
class CellPhoneNumber extends PhoneNumber {
public CellPhoneNumber(String phoneNumber) {
super(number);
}
}
class LandlinePhoneNumber extends PhoneNumber {
public LandlinePhoneNumber(String phoneNumber) {
super(number);
}
}
// ...number validation code
}
}
பரம்பரை உறவின் காரணமாக, ஒரு சந்ததி வகுப்பினுள் உள்ள உள்ளூர் வகுப்புகள் ஒரு மூதாதையரின் உள் வகுப்புகளை "பார்க்க". இறுதியாக, கடைசி குழுவிற்கு செல்லலாம் :)
உள் வகுப்புகள்
அதே வெளி வகுப்பில் (அல்லது அதன் வழித்தோன்றலில்) அறிவிக்கப்பட்ட ஒரு உள் வர்க்கம் மற்றொரு உள் வகுப்பைப் பெறலாம். உள் வகுப்புகள் பற்றிய பாடத்திலிருந்து சைக்கிள்களுடன் நமது உதாரணத்தைப் பயன்படுத்தி இதை ஆராய்வோம்.public class Bicycle {
private String model;
private int maxWeight;
public Bicycle(String model, int maxWeight) {
this.model = model;
this.maxWeight = maxWeight;
}
public void start() {
System.out.println("Let's go!");
}
class Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
class SportSeat extends Seat {
// ...methods
}
}
Seat
இங்கே வகுப்பின் உள்ளே உள்ள வகுப்பை அறிவித்தோம் Bicycle
. ஒரு சிறப்பு வகை பந்தய இருக்கை, SportSeat
, அதை மரபுரிமையாகப் பெறுகிறது. ஆனால், நாம் ஒரு தனி "பந்தய சைக்கிள்" வகையை உருவாக்கி அதை ஒரு தனி வகுப்பில் வைக்கலாம்:
public class SportBicycle extends Bicycle {
public SportBicycle(String model, int maxWeight) {
super(model, maxWeight);
}
class SportSeat extends Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
}
இதுவும் ஒரு விருப்பம். சந்ததியினரின் ( SportBicycle.SportSeat
) உள் வர்க்கம் மூதாதையரின் உள் வகுப்புகளை "பார்க்கிறது" மற்றும் அவற்றைப் பெற முடியும். உள் வகுப்புகளைப் பெறுவது ஒரு மிக முக்கியமான அம்சத்தைக் கொண்டுள்ளது! முந்தைய இரண்டு எடுத்துக்காட்டுகளில், எங்கள் SportSeat
வகுப்பு ஒரு உள் வகுப்பாக இருந்தது. SportSeat
ஆனால் உள் வகுப்பை ஒரே நேரத்தில் மரபுரிமையாகக் கொண்ட ஒரு சாதாரண பொது வகுப்பை உருவாக்க முடிவு செய்தால் என்ன செய்வது Seat
?
// Error! No enclosing instance of type 'Bicycle' is in scope
class SportSeat extends Bicycle.Seat {
public SportSeat() {
}
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
எங்களிடம் பிழை ஏற்பட்டது! ஏன் என்று உங்களால் யூகிக்க முடிகிறதா? :) இது எல்லாம் நேரடியானது. உள் வகுப்பைப் பற்றி நாம் பேசும்போது Bicycle.Seat
, வெளி வகுப்பின் ஒரு நிகழ்வைப் பற்றிய குறிப்பு உள் வகுப்பின் கட்டமைப்பாளருக்கு மறைமுகமாக அனுப்பப்பட்டதாகக் குறிப்பிட்டோம். Seat
ஒரு பொருளை உருவாக்காமல் ஒரு பொருளை உருவாக்க முடியாது என்பதே இதன் பொருள் Bicycle
. ஆனால் ஒரு உருவாக்கம் பற்றி என்ன SportSeat
? போலல்லாமல் Seat
, வெளிப்புற வகுப்பின் ஒரு நிகழ்வின் குறிப்பைக் கட்டமைப்பாளருக்கு மறைமுகமாக அனுப்புவதற்கான இந்த உள்ளமைக்கப்பட்ட வழிமுறை இல்லை. எஸ் வரை, ஒரு பொருள் இல்லாமல் , நாம் ஒரு பொருளை Bicycle
உருவாக்க முடியாது . எனவே, நாம் செய்ய ஒரே ஒரு விஷயம் மட்டுமே உள்ளது - ஒரு பொருளின் குறிப்பை கட்டமைப்பாளருக்கு வெளிப்படையாக அனுப்பவும் . அதை எப்படி செய்வது என்பது இங்கே: SportSeat
Seat
SportSeat
Bicycle
class SportSeat extends Bicycle.Seat {
public SportSeat(Bicycle bicycle) {
bicycle.super();
}
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
Now ஐப் பயன்படுத்தி சூப்பர் கிளாஸ் கன்ஸ்ட்ரக்டரை அழைக்கிறோம் super();
, நாம் ஒரு பொருளை உருவாக்க விரும்பினால் SportSeat
, இதைச் செய்வதிலிருந்து எதுவும் நம்மைத் தடுக்காது:
public class Main {
public static void main(String[] args) {
Bicycle bicycle = new Bicycle("Peugeot", 120);
SportSeat peugeotSportSeat = new SportSeat(bicycle);
}
}
அச்சச்சோ! இந்த பாடம் நீண்டது :) ஆனால் நீங்கள் நிறைய கற்றுக்கொண்டீர்கள்! இப்போது சில பணிகளைத் தீர்க்க வேண்டிய நேரம் இது! :)