JavaRush /جاوا بلاگ /Random-SD /وراثت ۾ داخل ٿيل طبقن جي

وراثت ۾ داخل ٿيل طبقن جي

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

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

اندروني طبقن جي وراثت جا مثال - 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 / باقاعدي، جامد / غير جامد - اهو مسئلو ناهي. هتي اسان اندروني طبقي کي وراثت ۾ رکون ٿا 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 {


       }

       //...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(); هاڻي، جيڪڏهن اسان ڪا شئي ٺاهڻ چاهيون ٿا 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