हाय! आज आपण एक महत्त्वाची यंत्रणा पाहू: नेस्टेड क्लासेसमधील वारसा. तुम्ही कधी विचार केला आहे का की तुम्हाला एखाद्या नेस्टेड क्लासला इतर वर्गाचा वारसा बनवायचा असेल तर तुम्ही काय कराल. नसल्यास, माझ्यावर विश्वास ठेवा: ही परिस्थिती गोंधळात टाकणारी असू शकते, कारण बर्याच बारकावे आहेत.
- आपण नेस्टेड क्लास इनहेरिट काही क्लास बनवत आहोत का? की आपण काही क्लास इनहेरिटला नेस्टेड क्लास बनवत आहोत?
- मूल/पालक वर्ग हा एक सामान्य सार्वजनिक वर्ग आहे किंवा तो देखील एक नेस्टेड वर्ग आहे?
- शेवटी, या सर्व परिस्थितींमध्ये आपण कोणत्या प्रकारचे नेस्टेड वर्ग वापरतो?
स्थिर नेस्टेड वर्ग
त्यांचे वारसा नियम सर्वात सोपे आहेत. येथे तुम्ही तुमच्या मनाच्या इच्छेनुसार काहीही करू शकता. एक स्थिर नेस्टेड वर्ग वारसा मिळवू शकतो:- एक सामान्य वर्ग
- बाह्य वर्ग किंवा त्याच्या पूर्वजांमध्ये घोषित केलेला स्थिर नेस्टेड वर्ग
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;
}
}
}
हे आम्हाला समजते. पण कोणते वर्ग स्थिर नेस्टेड वर्गाचा वारसा घेऊ शकतात? व्यावहारिकदृष्ट्या कोणतेही! नेस्टेड/नॉन-नेस्टेड, स्टॅटिक/नॉन-स्टॅटिक — काही फरक पडत नाही. येथे आपण 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
, बाह्य वर्गाच्या उदाहरणाचा संदर्भ कंस्ट्रक्टरला अस्पष्टपणे पास करण्यासाठी त्यात ही अंगभूत यंत्रणा नाही. S पर्यंत, ऑब्जेक्टशिवाय 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!");
}
}
आम्ही नाऊ वापरून सुपरक्लास कन्स्ट्रक्टर म्हणतो super();
, जर आम्हाला एखादी वस्तू तयार करायची असेल SportSeat
, तर असे करण्यापासून काहीही रोखणार नाही:
public class Main {
public static void main(String[] args) {
Bicycle bicycle = new Bicycle("Peugeot", 120);
SportSeat peugeotSportSeat = new SportSeat(bicycle);
}
}
ओफ्फ! हा धडा खूप मोठा होता :) पण तुम्ही खूप काही शिकलात! आता काही कार्ये सोडवण्याची वेळ आली आहे! :)
GO TO FULL VERSION