JavaRush /جاوا بلاگ /Random-UR /نیسٹڈ کلاسز کی وراثت

نیسٹڈ کلاسز کی وراثت

گروپ میں شائع ہوا۔
ہیلو! آج ہم ایک اہم میکانزم کے آپریشن کو دیکھیں گے - نیسٹڈ کلاسز میں وراثت۔ مجھے نہیں معلوم کہ کیا آپ نے کبھی اس کے بارے میں سوچا ہے کہ جب آپ کو کسی دوسرے سے نیسٹڈ کلاس وراثت میں لینے کی ضرورت ہو تو آپ کیا کریں گے۔ اگر نہیں، تو مجھ پر یقین کریں: یہ صورت حال پریشان کن ہوسکتی ہے، کیونکہ یہاں بہت سی باریکیاں ہیں
  1. کیا ہم کسی کلاس سے نیسٹڈ کلاس کو وراثت میں لیتے ہیں یا کیا ہم کسی نیسٹڈ کلاس سے وراثت میں آتے ہیں؟
  2. کیا جانشین/وراثت میں ملنے والا باقاعدہ عوامی طبقہ ہے، یا یہ بھی ایک نیسٹڈ کلاس ہے؟
  3. آخر میں، ہم ان تمام حالات میں کس قسم کی نیسٹڈ کلاسز استعمال کر رہے ہیں؟
اگر آپ ان تمام سوالوں کے جواب دیتے ہیں تو اتنے ممکنہ جوابات مل جائیں گے کہ آپ کا سر چکرا جائے گا :) جیسا کہ آپ جانتے ہیں، کسی پیچیدہ مسئلے کو حل کرنے کے لیے، آپ کو اسے آسان حصوں میں تقسیم کرنے کی ضرورت ہے۔ ہم یہی کریں گے۔ آئیے نیسٹڈ کلاسز کے ہر گروپ کو دو زاویوں سے دیکھتے ہیں: اس قسم کے نیسٹڈ کلاس سے کون وراثت میں مل سکتا ہے، اور کس سے وراثت میں مل سکتا ہے۔ آئیے جامد نیسٹڈ کلاسوں کے ساتھ شروع کریں۔

جامد نیسٹڈ کلاسز

اندرونی طبقات کی وراثت کی مثالیں - 2ان کے وراثت کے اصول سب سے آسان ہیں۔ یہاں آپ تقریباً ہر وہ کام کر سکتے ہیں جو آپ کا دل چاہے۔ ایک جامد نیسٹڈ کلاس اس سے وراثت میں مل سکتی ہے:
  • باقاعدہ کلاس
  • ایک جامد نیسٹڈ کلاس جس کا اعلان بیرونی طبقے یا اس کے آباؤ اجداد میں کیا جاتا ہے۔
آئیے سٹیٹک نیسٹڈ کلاسز کے بارے میں لیکچر کی مثال یاد رکھیں۔
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کر اسے صرف ایک عوامی کلاس بنا سکتے ہیں۔ کچھ بھی نہیں بدلے گا - یہ static nested سے بھی وراثت میں مل سکتا ہے 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 اقسام ہیں: صرف اندرونی کلاسز، لوکل کلاسز اور گمنام اندرونی کلاسز۔ داخلی طبقات کی وراثت کی مثالیں - 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 {


       }

       //...code валидации номера
   }
}
یہ مقامی کلاسوں کے بارے میں ہمارے لیکچر کا کوڈ ہے۔ نمبر کی تصدیق کرنے والی کلاس کے اندر ہمارے پاس ایک مقامی کلاس ہے PhoneNumber- فون نمبر۔ اگر اپنے مقاصد کے لیے ہمیں اس سے دو الگ الگ ہستیوں کو نکالنے کی ضرورت ہے، مثال کے طور پر، ایک موبائل فون نمبر اور ایک لینڈ لائن فون نمبر، تو ہم یہ کام صرف اسی طریقے سے کر سکتے ہیں۔ وجہ سادہ ہے: مقامی کلاس کا دائرہ اس طریقہ (بلاک) کے اندر ہوتا ہے جہاں اس کا اعلان کیا جاتا ہے۔ لہذا، ہم اسے کسی طرح بیرونی طور پر استعمال نہیں کر سکیں گے (بشمول وراثت کے لیے)۔ تاہم، خود مقامی طبقے کے پاس وراثت کے وسیع امکانات ہیں! ایک مقامی کلاس اس سے وراثت میں مل سکتی ہے:
  1. باقاعدہ کلاس۔
  2. ایک اندرونی طبقہ جو مقامی طبقے کے طور پر یا اس کے آباؤ اجداد میں قرار دیا جاتا ہے۔
  3. اسی طریقہ (بلاک) میں اعلان کردہ ایک اور مقامی کلاس سے۔
پہلا اور تیسرا نکات واضح نظر آتے ہیں، لیکن دوسرا تھوڑا سا الجھا ہوا ہے :/ آئیے دو مثالیں دیکھتے ہیں۔ مثال 1 - "اندرونی کلاس سے مقامی کلاس کو وراثت میں ملنا جسے مقامی کلاس کے طور پر اسی کلاس میں قرار دیا گیا تھا":
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);
           }
       }

       //...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);
           }
       }

       //...code валидации номера
   }
}
وراثت کے ذریعے رابطے کی بدولت، نسلی طبقے کے اندر مقامی کلاسیں آباؤ اجداد کے اندر کی اندرونی کلاسیں "دیکھیں"۔ اور آخر میں، چلتے ہیں آخری گروپ کی طرف :)

اندرونی کلاسز

ایک اندرونی طبقے کو اسی بیرونی طبقے (یا اس کی اولاد) میں اعلان کردہ دوسرے اندرونی طبقے سے وراثت میں مل سکتا ہے۔ آئیے اس کو اندرونی کلاسوں کے لیکچر سے اپنی سائیکل کی مثال کا استعمال کرتے ہوئے دیکھتے ہیں۔
public class Bicycle {

   private String model;
   private int mawWeight;

   public Bicycle(String model, int mawWeight) {
       this.model = model;
       this.mawWeight = mawWeight;
   }

   public void start() {
       System.out.println("Go!");
   }

   class Seat {

       public void up() {

           System.out.println("Сидение поднято выше!");
       }

       public void down() {

           System.out.println("Сидение опущено ниже!");
       }
   }

   class SportSeat extends Seat {

       //...methods
   }
}
یہاں ہم نے کلاس کے اندر Bicycleایک اندرونی کلاس کا اعلان کیا Seat- سیٹ۔ ریسنگ سیٹوں کی ایک خاص ذیلی قسم اس سے وراثت میں ملی تھی SportSeat۔ تاہم، ہم ایک الگ قسم کی "ریسنگ بائیکس" بنا سکتے ہیں اور اسے الگ کلاس میں رکھ سکتے ہیں:
public class SportBicycle extends Bicycle {

   public SportBicycle(String model, int mawWeight) {
       super(model, mawWeight);
   }


   class SportSeat extends Seat {

       public void up() {

           System.out.println("Сидение поднято выше!");
       }

       public void down() {

           System.out.println("Сидение опущено ниже!");
       }
   }
}
یہ بھی ممکن ہے۔ بچے کا اندرونی طبقہ ( SportBicycle.SportSeat) باپ دادا کے اندرونی طبقوں کو "دیکھتا" ہے اور ان سے وراثت حاصل کر سکتا ہے۔ اندرونی طبقات سے وراثت میں ایک بہت اہم خصوصیت ہے! پچھلی دو مثالوں میں ہمارے SportSeatپاس داخلی تھا۔ لیکن کیا ہوگا اگر ہم اسے SportSeatباقاعدہ پبلک کلاس بنانے کا فیصلہ کریں، جو اندرونی طبقے سے بھی وراثت میں ملتی ہے Seat؟
//ошибка! No inclosing instance of  type 'Bicycle' is in scope
class SportSeat extends Bicycle.Seat {

   public SportSeat() {

   }

   public void up() {

       System.out.println("Сидение поднято выше!");
   }

   public void down() {

       System.out.println("Сидение опущено ниже!");
   }
}
ہمیں ایک غلطی ہو گئی! کیا آپ اندازہ لگا سکتے ہیں کہ اس کا کیا تعلق ہے؟ :) یہ آسان ہے. جب ہم نے اندرونی طبقے کے بارے میں بات کی Bicycle.Seatتو ہم نے ذکر کیا کہ اندرونی طبقے کا کنسٹرکٹر واضح طور پر بیرونی طبقے کی کسی چیز کا حوالہ دیتا ہے۔ لہذا، ایک شے کو بنائے بغیر، Bicycleآپ کوئی چیز نہیں بنا سکتے Seat۔ تخلیق کے بارے میں کیا خیال ہے SportSeat؟ اس میں کنسٹرکٹر میں کسی بیرونی طبقے کی آبجیکٹ کا حوالہ واضح طور پر منتقل کرنے کے لئے وہی بلٹ ان میکانزم نہیں ہے جیسا کہ Seat. تاہم، کسی شے کے بغیر Bicycle، بالکل اسی طرح جیسے کے معاملے میں Seat، ہم کوئی چیز نہیں بنا سکتے SportSeat۔ لہذا، ہمارے پاس صرف ایک کام باقی ہے - واضح طور پر کنسٹرکٹر کو SportSeatآبجیکٹ کا حوالہ دیں۔ Bicycleیہاں یہ ہے کہ یہ کیسے ہوتا ہے:
class SportSeat extends Bicycle.Seat {

   public SportSeat(Bicycle bicycle) {

       bicycle.super();
   }

   public void up() {

       System.out.println("Сидение поднято выше!");
   }

   public void down() {

       System.out.println("Сидение опущено ниже!");
   }
}
اس کے لیے ہم ایک خاص لفظ استعمال کرتے ہیں super(); Now، اگر ہم کوئی چیز بنانا چاہتے ہیں SportSeatتو ہمیں ایسا کرنے سے کوئی چیز نہیں روکے گی۔
public class Main {

   public static void main(String[] args) {

       Bicycle bicycle = new Bicycle("Peugeot", 120);
       SportSeat peugeotSportSeat = new SportSeat(bicycle);

   }
}
افف، لیکچر کافی بڑا نکلا :) لیکن آپ نے بہت سی نئی چیزیں سیکھیں! اب کچھ مسائل کو حل کرنے کا وقت ہے! :)
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION