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

public class PhoneNumberValidator {
public void validatePhoneNumber(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;
}
}
// ...number validation code
}
}
முக்கியமான!நீங்கள் Java 7 ஐ நிறுவியிருந்தால், IDEA இல் ஒட்டும்போது இந்தக் குறியீடு தொகுக்கப்படாது. பாடத்தின் முடிவில் இதற்கான காரணங்களைப் பற்றி பேசுவோம். சுருக்கமாக, உள்ளூர் வகுப்புகள் எவ்வாறு செயல்படுகின்றன என்பது மொழியின் பதிப்பைப் பொறுத்தது. இந்தக் குறியீடு உங்களுக்காகத் தொகுக்கப்படவில்லை எனில், ஐடியாவில் உள்ள மொழிப் பதிப்பை ஜாவா 8க்கு மாற்றலாம் அல்லது final
இந்தச் சொல்லை முறை அளவுருவில் சேர்க்கலாம் validatePhoneNumber(final String number)
. அதன் பிறகு, எல்லாம் வேலை செய்யும். இது தொலைபேசி எண்களை சரிபார்க்கும் ஒரு சிறிய நிரலாகும். அதன் validatePhoneNumber()
முறை ஒரு சரத்தை உள்ளீடாக எடுத்து அது தொலைபேசி எண்ணா என்பதை தீர்மானிக்கிறது. இந்த முறையின் உள்ளே, நாங்கள் எங்கள் உள்ளூர் PhoneNumber
வகுப்பை அறிவித்தோம். ஏன் என்று நீங்கள் நியாயமாக கேட்கலாம். ஒரு முறைக்குள் ஒரு வகுப்பை ஏன் சரியாக அறிவிக்க வேண்டும்? சாதாரண உள் வகுப்பை ஏன் பயன்படுத்தக்கூடாது? உண்மை, நாம் செய்திருக்கலாம்PhoneNumber
வர்க்கம் ஒரு உள் வர்க்கம். ஆனால் இறுதி தீர்வு உங்கள் திட்டத்தின் கட்டமைப்பு மற்றும் நோக்கத்தைப் பொறுத்தது. உள் வகுப்புகள் பற்றிய பாடத்திலிருந்து எங்கள் உதாரணத்தை நினைவு கூர்வோம்:
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!");
}
public class HandleBar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left!");
}
}
}
அதில், HandleBar
பைக்கை இன்னர் கிளாஸ் செய்தோம். என்ன வித்தியாசம்? முதலில், வகுப்பைப் பயன்படுத்தும் விதம் வேறுபட்டது. முதல் எடுத்துக்காட்டில் உள்ள வகுப்பை விட இரண்டாவது எடுத்துக்காட்டில் உள்ள வர்க்கம் HandleBar
மிகவும் சிக்கலான நிறுவனமாகும் PhoneNumber
. முதலில், HandleBar
பொது right
மற்றும் left
முறைகள் உள்ளன (இவை செட்டர்கள்/ஜெட்டர்கள் அல்ல). இரண்டாவதாக, அது நமக்கு எங்கு தேவைப்படலாம் மற்றும் அதன் வெளிப்புற Bicycle
வகுப்பை முன்கூட்டியே கணிக்க இயலாது. ஒரு நிரலில் கூட டஜன் கணக்கான வெவ்வேறு இடங்கள் மற்றும் முறைகள் இருக்கலாம். ஆனால் வகுப்பில் PhoneNumber
, எல்லாம் மிகவும் எளிமையானது. எங்கள் திட்டம் மிகவும் எளிமையானது. இதற்கு ஒரே ஒரு நோக்கம் மட்டுமே உள்ளது: எண் சரியான ஃபோன் எண்ணா என்பதைச் சரிபார்க்க. பெரும்பாலான சந்தர்ப்பங்களில், எங்கள்PhoneNumberValidator
ஒரு முழுமையான நிரலாகக் கூட இருக்காது, மாறாக ஒரு பெரிய நிரலுக்கான அங்கீகார தர்க்கத்தின் ஒரு பகுதியாகும். எடுத்துக்காட்டாக, பயனர்கள் பதிவு செய்யும் போது பல்வேறு இணையதளங்கள் அடிக்கடி தொலைபேசி எண்ணைக் கேட்கின்றன. எண்களுக்குப் பதிலாக சில முட்டாள்தனங்களை நீங்கள் உள்ளிட்டால், வலைத்தளம் பிழையைப் புகாரளிக்கும்: "இது தொலைபேசி எண் அல்ல!" அத்தகைய வலைத்தளத்தின் டெவலப்பர்கள் (அல்லது, அதன் பயனர் அங்கீகார பொறிமுறை) எங்களுடையதைப் போன்ற ஒன்றைச் சேர்க்கலாம்PhoneNumberValidator
அவர்களின் குறியீட்டில். வேறு வார்த்தைகளில் கூறுவதானால், எங்களிடம் ஒரு முறையுடன் ஒரு வெளிப்புற வகுப்பு உள்ளது, இது நிரலில் ஒரே இடத்தில் பயன்படுத்தப்படும் மற்றும் வேறு எங்கும் இல்லை. அது பயன்படுத்தப்பட்டால், அதில் எதுவும் மாறாது: ஒரு முறை அதன் வேலையைச் செய்கிறது - அவ்வளவுதான். இந்த வழக்கில், அனைத்து தர்க்கங்களும் ஒரே முறையில் சேகரிக்கப்பட்டதால், கூடுதல் வகுப்பை இணைப்பது மிகவும் வசதியானதாகவும் சரியானதாகவும் இருக்கும். இது பெறுபவர் மற்றும் செட்டரைத் தவிர அதன் சொந்த முறைகள் இல்லை. உண்மையில், கட்டமைப்பாளரிடமிருந்து எங்களுக்கு தரவு மட்டுமே தேவை. இது மற்ற முறைகளில் ஈடுபடவில்லை. அதன்படி, அது பயன்படுத்தப்படும் ஒரே முறைக்கு வெளியே அதைப் பற்றிய தகவலை எடுக்க எந்த காரணமும் இல்லை. ஒரு உள்ளூர் வகுப்பு ஒரு முறையில் அறிவிக்கப்படும் ஒரு உதாரணத்தையும் நாங்கள் கொடுத்தோம், ஆனால் இது ஒரே விருப்பம் அல்ல. இது ஒரு குறியீடு தொகுதியில் எளிமையாக அறிவிக்கப்படலாம்:
public class PhoneNumberValidator {
{
class PhoneNumber {
private String phoneNumber;
public PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
}
public void validatePhoneNumber(String phoneNumber) {
// ...number validation code
}
}
அல்லது சுழலில் கூட for
!
public class PhoneNumberValidator {
public void validatePhoneNumber(String phoneNumber) {
for (int i = 0; i < 10; i++) {
class PhoneNumber {
private String phoneNumber;
public PhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
// ...some logic
}
// ...number validation code
}
}
ஆனால் இதுபோன்ற வழக்குகள் மிகவும் அரிதானவை. பெரும்பாலான சந்தர்ப்பங்களில், அறிவிப்பு முறைக்குள் நடக்கும். எனவே, நாங்கள் அறிவிப்புகளைக் கண்டுபிடித்தோம், மேலும் "தத்துவம்" பற்றியும் பேசினோம் :) உள் வகுப்புகளுடன் ஒப்பிடுகையில் உள்ளூர் வகுப்புகள் என்ன கூடுதல் அம்சங்கள் மற்றும் வேறுபாடுகளைக் கொண்டுள்ளன? உள்ளூர் வகுப்பின் ஒரு பொருளை அது அறிவிக்கப்பட்ட முறை அல்லது தொகுதிக்கு வெளியே உருவாக்க முடியாது. generatePhoneNumber()
ரேண்டம் ஃபோன் எண்ணை உருவாக்கி ஒரு பொருளைத் திருப்பி அனுப்பும் ஒரு முறை நமக்குத் தேவை என்று கற்பனை செய்து பாருங்கள் PhoneNumber
. எங்களின் தற்போதைய சூழ்நிலையில், எங்கள் வேலிடேட்டர் வகுப்பில் அத்தகைய முறையை உருவாக்க முடியாது:
public class PhoneNumberValidator {
public void validatePhoneNumber(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;
}
}
// ...number validation code
}
// Error! The compiler does not recognize the PhoneNumber class
public PhoneNumber generatePhoneNumber() {
}
}
உள்ளூர் வகுப்புகளின் மற்றொரு முக்கிய அம்சம் உள்ளூர் மாறிகள் மற்றும் முறை அளவுருக்களை அணுகும் திறன் ஆகும். நீங்கள் மறந்துவிட்டால், ஒரு முறைக்குள் அறிவிக்கப்பட்ட ஒரு மாறியானது "உள்ளூர்" மாறி எனப்படும். String usCountryCode
அதாவது, சில காரணங்களால் அந்த முறையின் உள்ளே ஒரு உள்ளூர் மாறியை உருவாக்கினால் validatePhoneNumber()
, அதை உள்ளூர் வகுப்பிலிருந்து அணுகலாம் PhoneNumber
. இருப்பினும், நிரலில் பயன்படுத்தப்படும் மொழியின் பதிப்பைப் பொறுத்து நிறைய நுணுக்கங்கள் உள்ளன. பாடத்தின் தொடக்கத்தில், உதாரணங்களில் ஒன்றின் குறியீடு ஜாவா 7 இல் தொகுக்கப்படாமல் போகலாம் என்று குறிப்பிட்டோம், நினைவிருக்கிறதா? இப்போது இதற்கான காரணங்களைக் கருத்தில் கொள்வோம் :) ஜாவா 7 இல், ஒரு லோக்கல் கிளாஸ் ஒரு லோக்கல் மாறி அல்லது மெத்தட் பாராமீட்டரை அணுக முடியும் final
.
public void validatePhoneNumber(String number) {
String usCountryCode = "+1";
class PhoneNumber {
private String phoneNumber;
// Error! The method parameter must be declared as final!
public PhoneNumber() {
this.phoneNumber = number;
}
public void printUsCountryCode() {
// Error! The local variable must be declared as final!
System.out.println(usCountryCode);
}
}
// ...number validation code
}
இங்கே கம்பைலர் இரண்டு பிழைகளை உருவாக்குகிறது. இங்கே எல்லாம் ஒழுங்காக உள்ளது:
public void validatePhoneNumber(final String number) {
final String usCountryCode = "+1";
class PhoneNumber {
private String phoneNumber;
public PhoneNumber() {
this.phoneNumber = number;
}
public void printUsCountryCode() {
System.out.println(usCountryCode);
}
}
// ...number validation code
}
பாடத்தின் தொடக்கத்தில் உள்ள குறியீடு ஏன் தொகுக்கப்படவில்லை என்பது இப்போது உங்களுக்குத் தெரியும்: ஜாவா 7 இல், ஒரு உள்ளூர் வகுப்பில் final
முறை அளவுருக்கள் மற்றும் final
உள்ளூர் மாறிகள் மட்டுமே அணுக முடியும். ஜாவா 8 இல், உள்ளூர் வகுப்புகளின் நடத்தை மாறிவிட்டது. மொழியின் இந்தப் பதிப்பில், ஒரு உள்ளூர் வகுப்பிற்கு final
உள்ளூர் மாறிகள் மற்றும் அளவுருக்களுக்கு மட்டும் அணுகல் உள்ளது effective-final
. Effective-final
துவக்கத்தில் இருந்து மதிப்பு மாறாத ஒரு மாறி ஆகும். usCountryCode
எடுத்துக்காட்டாக, ஜாவா 8 இல், கன்சோலில் மாறியை எளிதாகக் காட்டலாம் , அது இல்லாவிட்டாலும் கூட final
. முக்கிய விஷயம் என்னவென்றால், அதன் மதிப்பு மாறாது. பின்வரும் எடுத்துக்காட்டில், எல்லாம் சரியாக வேலை செய்கிறது:
public void validatePhoneNumber(String number) {
String usCountryCode = "+1";
class PhoneNumber {
public void printUsCountryCode() {
// Java 7 would produce an error here
System.out.println(usCountryCode);
}
}
// ...number validation code
}
ஆனால் துவக்கத்திற்குப் பிறகு உடனடியாக மாறியின் மதிப்பை மாற்றினால், குறியீடு தொகுக்கப்படாது.
public void validatePhoneNumber(String number) {
String usCountryCode = "+1";
usCountryCode = "+8";
class PhoneNumber {
public void printUsCountryCode() {
// Error!
System.out.println(usCountryCode);
}
}
// ...number validation code
}
ஒரு உள்ளூர் வர்க்கம் உள் வர்க்கத்தின் கருத்தின் ஒரு கிளையினமாக இருப்பதில் ஆச்சரியமில்லை! அவை பொதுவான பண்புகளையும் கொண்டுள்ளன. ஒரு உள்ளூர் வகுப்பிற்கு அனைத்து (தனியார் கூட) புலங்கள் மற்றும் வெளிப்புற வகுப்பின் முறைகளுக்கான அணுகல் உள்ளது: நிலையான மற்றும் நிலையானது அல்ல. String phoneNumberRegex
எடுத்துக்காட்டாக, எங்கள் வேலிடேட்டர் வகுப்பில் ஒரு நிலையான புலத்தைச் சேர்ப்போம் :
public class PhoneNumberValidator {
private static String phoneNumberRegex = "[^0-9]";
public void validatePhoneNumber(String phoneNumber) {
class PhoneNumber {
// ......
}
}
}
இந்த நிலையான மாறியைப் பயன்படுத்தி சரிபார்ப்பு செய்யப்படும். [^0-9]
அனுப்பப்பட்ட சரத்தில் வழக்கமான வெளிப்பாடு " " (அதாவது, 0 முதல் 9 வரையிலான இலக்கமாக இல்லாத எந்த எழுத்தும்) பொருந்தாத எழுத்துகள் உள்ளதா என்பதை இந்த முறை சரிபார்க்கிறது . உள்ளூர் வகுப்பில் இருந்து இந்த மாறியை நாம் எளிதாக அணுகலாம் PhoneNumber
. எடுத்துக்காட்டாக, பெறுபவரை எழுதுங்கள்:
public String getPhoneNumberRegex() {
return phoneNumberRegex;
}
உள்ளூர் வகுப்புகள் உள் வகுப்புகளைப் போலவே இருக்கும், ஏனெனில் அவை எந்த நிலையான உறுப்பினர்களையும் வரையறுக்கவோ அறிவிக்கவோ முடியாது. நிலையான முறைகளில் உள்ள உள்ளூர் வகுப்புகள் இணைக்கும் வகுப்பின் நிலையான உறுப்பினர்களை மட்டுமே குறிப்பிட முடியும். எடுத்துக்காட்டாக, நீங்கள் இணைக்கும் வகுப்பின் மாறியை (புலம்) நிலையானதாக வரையறுக்கவில்லை என்றால், ஜாவா கம்பைலர் ஒரு பிழையை உருவாக்குகிறது: "நிலையற்ற மாறியை நிலையான சூழலில் இருந்து குறிப்பிட முடியாது." உள்ளூர் வகுப்புகள் நிலையானவை அல்ல, ஏனெனில் அவை உள்ளடக்கிய தொகுதியில் உள்ள உறுப்பினர்களுக்கான அணுகலைக் கொண்டுள்ளன. இதன் விளைவாக, அவை பெரும்பாலான வகையான நிலையான அறிவிப்புகளைக் கொண்டிருக்க முடியாது. ஒரு தொகுதிக்குள் ஒரு இடைமுகத்தை நீங்கள் அறிவிக்க முடியாது: இடைமுகங்கள் இயல்பாகவே நிலையானவை. இந்த குறியீடு தொகுக்கப்படவில்லை:
public class PhoneNumberValidator {
public static void validatePhoneNumber(String number) {
interface I {}
class PhoneNumber implements I{
private String phoneNumber;
public PhoneNumber() {
this.phoneNumber = number;
}
}
// ...number validation code
}
}
ஆனால் ஒரு வெளிப்புற வகுப்பிற்குள் ஒரு இடைமுகம் அறிவிக்கப்பட்டால், PhoneNumber
வர்க்கம் அதை செயல்படுத்த முடியும்:
public class PhoneNumberValidator {
interface I {}
public static void validatePhoneNumber(String number) {
class PhoneNumber implements I{
private String phoneNumber;
public PhoneNumber() {
this.phoneNumber = number;
}
}
// ...number validation code
}
}
நிலையான துவக்கிகள் (தொடக்கத் தொகுதிகள்) அல்லது இடைமுகங்களை உள்ளூர் வகுப்புகளில் அறிவிக்க முடியாது. ஆனால் உள்ளூர் வகுப்புகள் நிலையான உறுப்பினர்களைக் கொண்டிருக்கலாம், அவை நிலையான மாறிகள் ( static final
). இப்போது நீங்கள் உள்ளூர் வகுப்புகளைப் பற்றி அறிந்திருக்கிறீர்கள், நண்பர்களே! நீங்கள் பார்க்க முடியும் என, அவர்கள் சாதாரண உள் வகுப்புகளிலிருந்து பல வேறுபாடுகளைக் கொண்டுள்ளனர். மொழியின் குறிப்பிட்ட பதிப்புகள் எவ்வாறு செயல்படுகின்றன என்பதைப் புரிந்துகொள்வதற்கு அவற்றின் அம்சங்களைக் கூட நாம் ஆராய வேண்டியிருந்தது :) அடுத்த பாடத்தில், அநாமதேய உள் வகுப்புகளைப் பற்றி பேசுவோம் - உள்ளமைக்கப்பட்ட வகுப்புகளின் கடைசி குழு. உங்கள் படிப்பில் நல்ல அதிர்ஷ்டம்! :)
GO TO FULL VERSION