CodeGym /جاوا بلاگ /Random-SD /حوالن جي قسمن کي وڌائڻ ۽ تنگ ڪرڻ
John Squirrels
سطح
San Francisco

حوالن جي قسمن کي وڌائڻ ۽ تنگ ڪرڻ

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

   public static void main(String[] args) {

       int bigNumber = 10000000;

       bigNumber = (short) bigNumber;

       System.out.println(bigNumber);

   }

}
اهو صرف اهو آهي جيڪو اسان مٿي ڏنل مثال ۾ ڪيو. آپريشن ڪيو ويو، پر ڇاڪاڻ ته shortمتغير 32 بائيٽن مان صرف 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. جئين ابتدائي قسمن سان، ريفرنس جا قسم خود بخود جاوا ۾ وسيع ٿي ويا آهن. توھان کي اھو ڪرڻ لاءِ اضافي ڪوڊ لکڻ جي ضرورت نه آھي. ھاڻي اسان وٽ ھڪڙو اولاد وارو اعتراض آھي جيڪو والدين حوالي سان لڳايو ويو آھي. نتيجي طور، اسان ڏسون ٿا ته طريقو ڪال اولاد طبقي تي ڪيو ويو آهي. جيڪڏهن توهان اڃا تائين مڪمل طور تي نه سمجهي رهيا آهيو ته هي ڪوڊ ڇو ڪم ڪري ٿو، ان کي سادي ٻولي ۾ ٻيهر لکو:
Animal animal = new DomesticatedAnimal();
هن سان ڪو مسئلو ناهي، صحيح؟ تصور ڪريو ته اها حقيقي زندگي آهي، ۽ حوالو صرف هڪ پيپر ليبل آهي جنهن تي 'جانور' لکيل آهي. جيڪڏهن توهان ڪاغذ جو اهو ٽڪرو وٺو ۽ ان کي ڪنهن به پالتو جانور جي ڪالر سان ڳنڍيو، هر شيء صحيح ٿي ويندي. سڀ کان پوء، ڪنهن به پالتو جانور هڪ جانور آهي! ريورس عمل - وراثت واري وڻ کي اولاد ڏانهن منتقل ڪرڻ - تنگ ٿي رهيو آهي:
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!
   }
}
مرتب ڪندڙ هڪ غلطي پيدا ڪري ٿو! پر ڇو؟ ڇو ته توھان ڪوشش ڪري رھيا آھيو ھڪڙي والدين اعتراض کي اولاد جي حوالي سان تفويض ڪرڻ. ٻين لفظن ۾، توهان هن وانگر ڪجهه ڪرڻ جي ڪوشش ڪري رهيا آهيو:
DomesticatedAnimal domesticatedAnimal = new Animal();
خير، ٿي سگهي ٿو هر شي ڪم ڪندو جيڪڏهن اسان واضح طور تي اهو قسم بيان ڪريون جنهن کي اسان تبديل ڪرڻ جي ڪوشش ڪري رهيا آهيون؟ اهو انگن سان ڪم ڪيو - اچو ته اها ڪوشش ڪريون! :)
public class Main {

   public static void main(String[] args) {

       Pet pet = (Pet) new Animal();
   }
}
سلسلي ۾ استثنا "main" java.lang.ClassCastException: جانورن کي پالتو جانور جي غلطي تي اڇلائي نٿو سگهجي ! مرتب ڪندڙ هن وقت اسان تي نه چيا، پر اسان هڪ استثنا سان ختم ڪيو. اسان اڳ ۾ ئي سبب ڄاڻون ٿا: اسان ڪوشش ڪري رهيا آهيون والدين اعتراض کي اولاد جي حوالي سان تفويض ڪرڻ. پر توهان اهو ڇو نٿا ڪري سگهو؟ ڇو ته سڀ جانور Domesticated Animals نه آهن. توھان ھڪڙو 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 = new Pet();
پر آخري مثال ۾، اهو هڪ Animalاعتراض هو:
Pet pet = (Pet) new Animal();
توهان هڪ آبجاري اعتراض کي اولاد جي متغير کي تفويض نٿا ڪري سگهو. توهان مخالف ڪري سگهو ٿا.
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION