JavaRush /جاوا بلاگ /Random-SD /حوالن جي قسمن جي توسيع ۽ تڪرار

حوالن جي قسمن جي توسيع ۽ تڪرار

گروپ ۾ شايع ٿيل
سلام! پوئين ليڪچرن مان هڪ ۾، اسان بنيادي قسمن جي کاسٽ ڪرڻ تي بحث ڪيو. اچو ته مختصر طور تي ياد رکون ته اسان ڇا ڳالهائي رهيا هئاسين. حوالن جي قسمن جي توسيع ۽ تڪرار - 1اسان اڳين قسمن جي نمائندگي ڪئي (هن صورت ۾، انگن اکرن ۾) nesting dolls جي ميموري جي مقدار جي مطابق جيڪي انهن تي قبضو ڪن ٿا. جئين توهان کي ياد آهي، هڪ ننڍڙي نيسٽنگ گڏي کي وڏي ۾ رکڻ آسان هوندو حقيقي زندگي ۽ جاوا پروگرامنگ ۾.
public class Main {
   public static void main(String[] args) {
        short smallNumber = 100;
        int bigNumber =  smallNumber;
        System.out.println(bigNumber);
   }
}
هي هڪ مثال آهي خودڪار تبديلي، يا واڌارو . اهو پنهنجو پاڻ تي ٿئي ٿو، تنهنڪري اضافي ڪوڊ لکڻ جي ڪا ضرورت ناهي. آخر ۾، اسان ڪجھ به غير معمولي نه ڪري رهيا آهيون: اسان صرف هڪ ننڍڙي نيسٽنگ گولي کي وڏي nesting گڏي ۾ وجهي رهيا آهيون. اها ٻي ڳالهه آهي ته اسان ان جي ابتڙ ڪرڻ جي ڪوشش ڪريون ۽ هڪ وڏي ميٽريوشڪا گڏي کي ننڍي ۾ وجهي. اهو زندگي ۾ نه ٿو ڪري سگهجي، پر پروگرامنگ ۾ اهو ڪري سگهجي ٿو. پر اتي هڪ caveat آهي. جيڪڏهن اسان هڪ قدر کي intمتغير ۾ رکڻ جي ڪوشش ڪنداسين short، اهو آسانيء سان ڪم نه ڪندو. سڀ کان پوء، معلومات جا صرف 16 بٽ هڪ متغير ۾ فٽ ٿي سگهن ٿا short، پر قيمت int32 بٽ وٺندو آهي! نتيجي طور، منتقلي قدر خراب ٿي ويندي. مرتب ڪندڙ اسان کي هڪ غلطي ڏيندو (" دوست، توهان ڪجهه مشڪوڪ ڪم ڪري رهيا آهيو! ")، پر جيڪڏهن اسان واضح طور تي بيان ڪريون ٿا ته اسان ڪهڙي قسم جي قيمت کي وڌايو آهي، اهو اڃا تائين اهڙي آپريشن کي انجام ڏيندو.
public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       bigNumber = (short) bigNumber;

       System.out.println(bigNumber);

   }

}
مٿين مثال ۾، اسان اهو ئي ڪيو. آپريشن مڪمل ڪيو ويو، پر short32 مان صرف 16 بٽ متغير ۾ ٺھيل آھن، حتمي قدر خراب ٿي وئي، ۽ نتيجي ۾ اسان نمبر -27008 حاصل ڪيو . ھن آپريشن کي چئبو آھي واضح تبديلي، يا تنگ ڪرڻ .

حوالن جي قسمن جي توسيع ۽ تڪرار جا مثال

هاڻي اسان ساڳين عملن جي باري ۾ ڳالهائينداسين، پر قابل اطلاق ابتدائي قسمن تي نه، پر شيون ۽ حوالن جي متغيرن تي ! جاوا ۾ اهو ڪيئن ڪم ڪندو آهي؟ بلڪل سادو اصل ۾. اهڙيون شيون آهن جيڪي هڪ ٻئي سان لاڳاپيل نه آهن. اهو سمجهڻ منطقي هوندو ته اهي هڪ ٻئي ۾ تبديل نٿا ٿي سگهن يا ته واضح طور تي يا خودڪار طور تي:
public class Cat {
}

public class Dog {
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Dog();//error!

   }

}
هتي اسان، يقينا، هڪ غلطي حاصل ڪنداسين. ڪلاس هڪ ٻئي سان لاڳاپيل نه Catآهن Dog، ۽ اسان هڪ کان ٻئي ڏانهن "ڪنورٽر" نه لکيو آهي. اهو منطقي آهي ته اسان اهو ڪرڻ جي قابل نه هوندا: مرتب ڪندڙ کي خبر ناهي ته انهن شين کي هڪ ٻئي جي وچ ۾ ڪيئن بدلجي. اها ٻي ڳالهه آهي ته شيون هڪ ٻئي سان ڳنڍيل آهن! ڪيئن؟ سڀ کان پهريان، وراثت استعمال ڪندي. اچو ته وراثت سان هڪ ننڍڙو طبقاتي نظام ٺاهڻ جي ڪوشش ڪريون. اسان وٽ ھڪڙو عام طبقو ھوندو جيڪو جانورن جي نمائندگي ڪندو:
public class Animal {

   public void introduce() {

       System.out.println("i'm Animal");
   }
}
جانور، جيئن توهان ڄاڻو ٿا، گهريلو ۽ جهنگلي آهن:
public class WildAnimal extends Animal {

   public void introduce() {

       System.out.println("i'm WildAnimal");
   }
}

public class Pet extends Animal {

   public void introduce() {

       System.out.println("i'm Pet");
   }
}
مثال طور، اچو ته ڪتا وٺون - هڪ گهريلو ڪتو ۽ هڪ ڪوئٽ:
public class Dog extends Pet {

   public void introduce() {

       System.out.println("i'm Dog");
   }
}





public class Coyote extends WildAnimal {

   public void introduce() {

       System.out.println("i'm Coyote");
   }
}
اسان جا طبقا عمدي طور تي سڀ کان وڌيڪ ابتدائي آهن انهن کي سمجهڻ آسان بڻائي. اسان کي هتي فيلڊ جي ضرورت ناهي، ۽ هڪ طريقو ڪافي آهي. اچو ته ھيٺ ڏنل ڪوڊ کي هلائڻ جي ڪوشش ڪريو:
public class Main {

   public static void main(String[] args) {

       Animal animal = new Pet();
       animal.introduce();
   }
}
ڇا توهان سوچيو ٿا ته ڪنسول ڏانهن آئوٽ ٿيندو؟ introduceڇا ڪلاس Petيا ڪلاس جو طريقو ڪم ڪندو Animal؟ پڙھڻ جاري رکڻ کان اڳ پنھنجي جواب کي درست ڪرڻ جي ڪوشش ڪريو. ۽ هتي نتيجو آهي! مان پالتو آهيان جواب هن طرح ڇو نڪتو؟ اهو سادو آهي. اسان وٽ ھڪڙو والدين متغير ۽ ھڪڙو ٻار اعتراض آھي. لکڻ سان:
Animal animal = new Pet();
اسان ھڪڙو حوالو قسم وڌايوPet آھي ۽ ان جي اعتراض کي متغير ۾ محفوظ ڪيو آھي Animal. جئين ابتدائي قسمن سان، جاوا ۾ حوالن جي قسمن جي توسيع خودڪار ٿي ويندي آهي. ان لاءِ اضافي ڪوڊ لکڻ جي ڪا ضرورت ناهي. ھاڻي اسان وٽ ھڪڙو ٻاراڻو اعتراض آھي جيڪو والدين جي حوالي سان ڳنڍيل آھي، ۽ نتيجي ۾ اسين ڏسون ٿا ته طريقو چائلڊ ڪلاس تي سڏيو ويندو آھي. جيڪڏهن توهان اڃا تائين مڪمل طور تي نه ٿا سمجهو ته هي ڪوڊ ڇو ڪم ڪري ٿو، ان کي سادي ٻولي ۾ ٻيهر لکو:
Животное животное = new ДомашнееЖивотное();
انهي سان ڪو مسئلو ناهي، صحيح؟ تصور ڪريو ته هي حقيقي زندگي آهي، ۽ هن معاملي ۾ لنڪ هڪ سادي پيپر ٽيگ آهي جيڪو چوي ٿو "جانور." جيڪڏھن توھان ڪاغذ جو ھڪڙو ٽڪرو وٺو ۽ ان کي ڪنھن پالتو جانور جي ڪالر سان ڳنڍيو، سڀ ڪجھ ٺيڪ ٿي ويندو. ڪو به پالتو جانور اڃا تائين هڪ جانور آهي! ريورس عمل، يعني وراثت واري وڻ کي وارثن ڏانهن منتقل ڪرڻ، هڪ تنگ آهي:
public class Main {

   public static void main(String[] args) {

       WildAnimal wildAnimal = new Coyote();

       Coyote coyote = (Coyote) wildAnimal;

       coyote.introduce();
   }
}
جئين توهان ڏسي سگهو ٿا، هتي اسان واضح طور تي ظاهر ڪريون ٿا ته اسان پنهنجي اعتراض کي ڪهڙي طبقي ڏانهن اڇلائڻ چاهيون ٿا. اڳي اسان وٽ ھڪڙو متغير ھو WildAnimal، ۽ ھاڻي Coyote، جيڪو وراثت واري وڻ ھيٺ وڃي ٿو. اهو منطقي آهي ته ڪمپلر اهڙي آپريشن کي ڪنهن واضح اشاري کان سواءِ نه ڇڏيندو، پر جيڪڏهن توهان قوس ۾ قسم بيان ڪريو ته سڀ ڪجهه ڪم ڪندو. حوالن جي قسمن جي توسيع ۽ تڪرار - 2 اچو ته هڪ ٻيو مثال ڏسو، وڌيڪ دلچسپ:
public class Main {

   public static void main(String[] args) {

       Pet pet = new Animal();//error!
   }
}
مرتب ڪندڙ هڪ غلطي اڇلائي ٿو! ان جو سبب ڇا آهي؟ حقيقت اها آهي ته توهان ڪوشش ڪري رهيا آهيو والدين اعتراض کي ٻار جي متغير ڏانهن تفويض ڪرڻ. ٻين لفظن ۾، توھان ھي ڪرڻ چاھيو ٿا:
ДомашнееЖивотное домашнееЖивотное = new Животное();
پر ٿي سگهي ٿو ته جيڪڏهن اسان واضح طور تي ظاهر ڪيو ته قسم جو اسان اڇلائڻ جي ڪوشش ڪري رهيا آهيون، اسان ڪامياب ٿينداسين؟ انگ ڪم ڪرڻ لڳي، اچو ته ڪوشش ڪريون! :)
public class Main {

   public static void main(String[] args) {

       Pet pet = (Pet) new Animal();
   }
}
سلسلي ۾ استثنا "main" java.lang.ClassCastException: جانورن کي پالتو جانور جي غلطي تي اڇلائي نٿو سگهجي ! مرتب ڪندڙ هن ڀيري شڪايت نه ڪئي، پر نتيجي طور اسان کي هڪ استثنا مليو. اسان اڳ ۾ ئي سبب ڄاڻون ٿا: اسان ڪوشش ڪري رهيا آهيون والدين اعتراض کي ٻار جي متغير ڏانهن تفويض ڪرڻ. ڇو، حقيقت ۾، اهو نه ٿو ڪري سگهجي؟ ڇو ته سڀئي جانور پالتو نه آهن. توھان ھڪڙو اعتراض ٺاھيو آھي Animal۽ ان کي متغير کي تفويض ڪرڻ جي ڪوشش ڪري رھيا آھيو Pet. پر، مثال طور، ڪويوٽ پڻ آهي Animal، پر اهو نه آهي Pet، هڪ گهريلو جانور. ٻين لفظن ۾، جڏهن توهان لکندا آهيو:
Pet pet = (Pet) new Animal();
new Animal()ڪو به جانور اتي ٿي سگهي ٿو، ۽ اهو گهريلو هجڻ ضروري ناهي! قدرتي طور تي، توهان جو متغير Pet petصرف پالتو جانور (۽ انهن جي اولاد) کي محفوظ ڪرڻ لاء مناسب آهي، ۽ هر ڪنهن لاء نه. تنهن ڪري، اهڙين حالتن لاء، جاوا ۾ هڪ خاص استثنا پيدا ڪيو ويو آهي - ClassCastExceptionهڪ غلطي جڏهن ڪلاس کي ترتيب ڏيڻ. اچو ته ان کي ٻيهر صاف ڪرڻ لاء ٻيهر چئون. هڪ والدين متغير (حوالو) هڪ نسلي طبقي جي اعتراض ڏانهن اشارو ڪري سگهي ٿو:
public class Main {

   public static void main(String[] args) {

       Pet pet =  new Pet();
       Animal animal = pet;

       Pet pet2 = (Pet) animal;
       pet2.introduce();
   }
}
مثال طور، اسان کي هتي ڪو مسئلو نه ٿيندو. اسان وٽ ھڪڙو اعتراض آھي Petجيڪو ھڪڙي لنڪ ذريعي اشارو ڪيو ويو آھي Pet. ان کان پوء هڪ نئين لنڪ ساڳئي اعتراض ڏانهن اشارو ڪرڻ شروع ڪيو Animal. animalجنهن کان پوء اسان کي تبديل ڪريون ٿا Pet. اسان اهو ڇو ڪيو، رستي جي ذريعي؟ آخري دفعو اسان کي هڪ استثنا مليو! ڇو ته هن وقت اسان جو اصل مقصد آهي Pet pet!
Pet pet =  new Pet();
۽ پوئين مثال ۾ اهو هڪ اعتراض هو Animal:
Pet pet = (Pet) new Animal();
هڪ نسلي متغير کي ڪنهن اباڻي شئي مقرر نه ٿو ڪري سگهجي. ان جي برعڪس، توهان اهو ڪري سگهو ٿا.
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION