CodeGym /جاوا بلاگ /Random-SD /نرالي طبقن جي وراثت جا مثال
John Squirrels
سطح
San Francisco

نرالي طبقن جي وراثت جا مثال

گروپ ۾ شايع ٿيل
سلام اڄ اسان هڪ اهم ميکانيزم تي نظر ڪنداسين: وراثت ۾ نيسٽ ٿيل طبقن ۾. ڇا توهان ڪڏهن سوچيو آهي ته توهان ڇا ڪندا جيڪڏهن توهان کي ضرورت هجي ته هڪ نيسٽڊ ڪلاس کي ڪنهن ٻئي طبقي جو وارث بڻايو وڃي. جيڪڏهن نه، مون تي يقين ڪريو: اها صورتحال مونجهارو ٿي سگهي ٿي، ڇاڪاڻ ته اتي تمام گهڻيون شيون آهن.
  1. ڇا اسان نيسٽڊ ڪلاس کي ڪنهن طبقي جو وارث بڻائي رهيا آهيون؟ يا اسان ڪنهن طبقي کي نرالي طبقي جو وارث بڻائي رهيا آهيون؟
  2. ڇا ٻار/والدين طبقو هڪ عام عوامي طبقو آهي، يا اهو پڻ هڪ نرالو طبقو آهي؟
  3. آخرڪار، انهن سڀني حالتن ۾ اسان ڪهڙي قسم جي nested طبقن کي استعمال ڪندا آهيون؟
انهن سڀني سوالن جا تمام گهڻا ممڪن جواب آهن، توهان جو مٿو ڦري ويندو :) جيئن توهان ڄاڻو ٿا، اسان هڪ پيچيده مسئلو حل ڪري سگهون ٿا ان کي آسان حصن ۾ ورهائي. اچو ته اهو ڪريون. اچو ته غور ڪريون هر هڪ گروهه جي nested طبقن جي بدلي ۾ ٻن نقطن کان: ڪير هر قسم جي nested طبقي جو وارث ٿي سگهي ٿو، ۽ ڪير اهو وارث ٿي سگهي ٿو. اچو ته static nested classes سان شروع ڪريون.

جامد نسٽڊ ڪلاس

نراس ٿيل طبقن جي وراثت جا مثال - 2سندن وراثت جا ضابطا سڀ کان سادو آهن. هتي توهان تقريبا هر شي ڪري سگهو ٿا جيڪو توهان جي دل چاهي ٿو. هڪ جامد نسٽڊ ڪلاس وارث ٿي سگھي ٿو:
  • هڪ عام طبقي
  • هڪ جامد نسٽڊ ڪلاس جيڪو ٻاهرئين طبقي يا ان جي ابن ڏاڏن ۾ اعلان ڪيو ويو آهي
static nested classes تي اسان جي سبق مان هڪ مثال ياد ڪريو.
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