CodeGym /جاوا بلاگ /Random-UR /نیسٹڈ کلاسز کی وراثت کی مثالیں۔
John Squirrels
سطح
San Francisco

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

گروپ میں شائع ہوا۔
ہائے! آج ہم ایک اہم طریقہ کار دیکھیں گے: نیسٹڈ کلاسز میں وراثت۔ کیا آپ نے کبھی اس بارے میں سوچا ہے کہ اگر آپ کو نیسٹڈ کلاس کو کسی اور کلاس کا وارث بنانے کی ضرورت ہو تو آپ کیا کریں گے۔ اگر نہیں، تو مجھ پر یقین کریں: یہ صورت حال مبہم ہوسکتی ہے، کیونکہ بہت ساری باریکیاں ہیں۔
  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;
       }
   }
}
ہم یہ سمجھتے ہیں۔ لیکن کون سی کلاسیں جامد نیسٹڈ کلاس کا وارث ہوسکتی ہیں؟ عملی طور پر کوئی بھی! 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 اقسام میں آتے ہیں: سادہ اندرونی کلاسز، لوکل کلاسز، اور گمنام اندرونی کلاسز۔ نیسٹڈ کلاسز کی وراثت کی مثالیں - 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مقامی کلاس ہے۔ اگر ہمیں دو الگ الگ اداروں کی نمائندگی کرنے کی ضرورت ہے، مثال کے طور پر، ایک موبائل فون نمبر اور ایک لینڈ لائن فون نمبر، تو ہم یہ صرف اسی طریقہ کے اندر کر سکتے ہیں۔ وجہ سادہ ہے: مقامی کلاس کا دائرہ کار اس طریقہ (کوڈ بلاک) تک محدود ہے جہاں اسے اعلان کیا جاتا ہے۔ نتیجے کے طور پر، ہم اسے بیرونی طور پر استعمال نہیں کر پائیں گے (بشمول طبقاتی وراثت کے لیے)۔ تاہم، خود مقامی طبقے کے اندر وراثت کے امکانات بہت وسیع ہیں! ایک مقامی کلاس وراثت میں مل سکتی ہے:
  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);
           }
       }

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

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