CodeGym /جاوا بلاگ /Random-SD /عام ۾ وائلڊ ڪارڊ
John Squirrels
سطح
San Francisco

عام ۾ وائلڊ ڪارڊ

گروپ ۾ شايع ٿيل
سلام اچو ته generics جو مطالعو جاري رکون. توھان اڳئين سبقن مان انھن جي باري ۾ ڪافي ڄاڻ حاصل ڪري چڪا آھيو ( جڏھن generics سان ڪم ڪرڻ وقت varargs استعمال ڪرڻ بابت ۽ قسم erasure جي باري ۾ )، پر ھڪڙو اھم موضوع آھي جنھن تي اسان اڃا غور نہ ڪيو آھي - وائلڊ ڪارڊ . هي generics جي تمام اهم خصوصيت آهي. ايتري قدر جو اسان ان لاءِ هڪ الڳ سبق وقف ڪيو آهي! اهو چيو ته، وائلڊ ڪارڊ بابت خاص طور تي پيچيده ڪجھ به ناهي. توهان اهو ڏسندا ته فوري طور تي :) وائلڊ ڪارڊ عام ۾ - 1اچو ته هڪ مثال ڏسو:
public class Main {

   public static void main(String[] args) {

       String str = new String("Test!");
       // No problem
       Object obj = str;

       List<String> strings = new ArrayList<String>();
       // Compilation error!
       List<Object> objects = strings;
   }
}
هتي ڇا ٿي رهيو آهي؟ اسان ٻه تمام گهڻيون حالتون ڏسون ٿا. صورت ۾، اسان هڪ اعتراض Stringکي هڪ Objectاعتراض اڇلايو. هتي ڪو به مسئلو ناهي - هر شي ڪم ڪري ٿي جيئن توقع ڪئي وئي. پر ٻئي صورتحال ۾، مرتب ڪندڙ هڪ غلطي پيدا ڪري ٿو. پر اسان ساڳيو ڪم ڪري رهيا آهيون، اسان نه آهيون؟ هن ڀيري اسان صرف استعمال ڪري رهيا آهيون ڪيترن ئي شين جو مجموعو. پر غلطي ڇو ٿئي ٿي؟ ڪهڙو فرق آهي؟ ڇا اسان ھڪڙي اعتراض کي ھڪڙي يا 20 شين Stringتي اڇلائي رھيا آھيون؟ ڪنهن شئي ۽ شين جي مجموعنObject جي وچ ۾ هڪ اهم فرق آهي . جيڪڏهن ڪلاس ڪلاس جو ٻار آهي ته پوءِ ڪلاس جو ٻار ناهي . اهو ئي سبب آهي جو اسان پنهنجي ڪاسٽ ڪرڻ جي قابل نه هئاسين . جو ٻار آهي ، پر جو ٻار ناهي . اهو شايد سپر وجداني نه لڳي. ٻوليءَ جي تخليقڪارن ائين ڇو ڪيو؟ اچو ته تصور ڪريون ته مرتب ڪندڙ اسان کي غلطي نه ڏئي: BACollection<B>Collection<A>List<String>List<Object>StringObjectList<String>List<Object>
List<String> strings = new ArrayList<String>();
List<Object> objects = strings;
هن معاملي ۾، اسان ڪري سگهون ٿا، مثال طور، هيٺيون ڪم:
objects.add(new Object());
String s = strings.get(0);
ڇاڪاڻ ته مرتب ڪندڙ اسان کي ڪا به غلطي نه ڏني ۽ اسان کي هڪ List<Object>حوالو ٺاهڻ جي اجازت ڏني جيڪا اشارو ڪري ٿي strings، اسان مجموعي Object۾ ڪنهن به پراڻي اعتراض کي شامل ڪري سگهون ٿا strings! ان ڪري، اسان اها گارنٽي وڃائي چڪا آهيون ته اسان جي مجموعن ۾ صرف اهي Stringشيون شامل آهن جيڪي عام قسم جي دعوت ۾ قسم جي دليل طرفان بيان ڪيل آهن . ٻين لفظن ۾، اسان generics جو بنيادي فائدو وڃائي ڇڏيو آهي - قسم جي حفاظت. ۽ ڇاڪاڻ ته مرتب ڪندڙ اسان کي ائين ڪرڻ کان نه روڪيو، اسان کي صرف رن ٽائيم تي هڪ غلطي ملندي، جيڪا هميشه هڪ تاليف جي غلطي کان وڌيڪ خراب آهي. اهڙين حالتن کي روڪڻ لاء، مرتب ڪندڙ اسان کي هڪ غلطي ڏئي ٿو:
// Compilation error
List<Object> objects = strings;
...۽ اسان کي ياد ڏياريندو آهي ته ان List<String>جو اولاد ناهي List<Object>. هي عام ماڻهن لاءِ هڪ لوهه جو قاعدو آهي، ۽ اهو ياد رکڻ گهرجي جڏهن انهن سان ڪم ڪيو وڃي. اچو ته اڳتي وڌون. فرض ڪريو اسان وٽ ھڪڙو ننڍڙو طبقو آھي:
public class Animal {

   public void feed() {

       System.out.println("Animal.feed()");
   }
}

public class Pet extends Animal {

   public void call() {

       System.out.println("Pet.call()");
   }
}

public class Cat extends Pet {

   public void meow() {

       System.out.println("Cat.meow()");
   }
}
درجي بندي هڪ سادي جانورن جي طبقي طرفان مٿي آهي، جيڪو پالتو جانور طرفان وراثت ۾ آهي. پالتو جانورن جا 2 ذيلي ڪلاس آھن: ڪتو ۽ ٻلي. هاڻي فرض ڪريو ته اسان کي هڪ سادي iterateAnimals()طريقو ٺاهڻ جي ضرورت آهي. طريقي کي ڪنهن به جانورن جو مجموعو وٺڻ گهرجي ( Animal, Pet, Cat, Dog)، سڀني عناصرن تي ٻيهر ورجائي، ۽ هر ورجائي دوران ڪنسول تي پيغام ڏيکاري. اچو ته اهڙي طريقي سان لکڻ جي ڪوشش ڪريون:
public static void iterateAnimals(Collection<Animal> animals) {

   for(Animal animal: animals) {

       System.out.println("Another iteration in the loop!");
   }
}
لڳي ٿو ته مسئلو حل ٿي ويو آهي! بهرحال، جيئن اسان تازو سکيو آهي، List<Cat>۽ List<Dog>ان List<Pet>جو اولاد نه آهن List<Animal>! هن جو مطلب اهو آهي ته جڏهن اسان iterateAnimals()ٻلين جي فهرست سان طريقي سان سڏڻ جي ڪوشش ڪندا آهيون، اسان کي گڏ ڪرڻ جي غلطي ملي ٿي:
import java.util.*;

public class Main3 {


   public static void iterateAnimals(Collection<Animal> animals) {

       for(Animal animal: animals) {

           System.out.println("Another iteration in the loop!");
       }
   }

   public static void main(String[] args) {


       List<Cat> cats = new ArrayList<>();
       cats.add(new Cat());
       cats.add(new Cat());
       cats.add(new Cat());
       cats.add(new Cat());

       // Compilation error!
       iterateAnimals(cats);
   }
}
اسان لاءِ حالتون تمام سٺيون نه لڳيون! ڇا اسان کي هر قسم جي جانورن جي ڳڻپ لاءِ الڳ الڳ طريقا لکڻ گهرجن؟ دراصل، نه، اسان نٿا ڪريون :) ۽ جيئن ائين ٿئي ٿو، وائلڊ ڪارڊ اسان جي مدد ڪري ٿو! اسان هيٺ ڏنل تعمير استعمال ڪندي هڪ سادي طريقي سان مسئلو حل ڪري سگهون ٿا:
public static void iterateAnimals(Collection<? extends Animal> animals) {

   for(Animal animal: animals) {

       System.out.println("Another iteration in the loop!");
   }
}
هي هڪ وائلڊ ڪارڊ آهي. وڌيڪ واضح طور تي، هي وائلڊ ڪارڊ جي ڪيترن ئي قسمن مان پهريون آهي. اهو هڪ مٿاهين-حدود وائلڊ ڪارڊ طور سڃاتو وڃي ٿو ۽ ان جو اظهار ڪيو ويو آهي ؟ وڌائي ٿو . هي تعمير اسان کي ڇا ٻڌائي ٿو؟ هن جو مطلب اهو آهي ته طريقو Animalشيون يا ڪنهن به طبقي جي شين جو هڪ مجموعو قبول ڪري ٿو جيڪو Animal(؟ جانورن کي وڌايو). ٻين لفظن ۾، طريقو قبول ڪري سگھي ٿو Animal, Pet, Dog, يا Catشين جو مجموعو - ان ۾ ڪو فرق نه پوندو. اچو ته پاڻ کي قائل ڪريون ته اهو ڪم ڪري ٿو:
public static void main(String[] args) {

   List<Animal> animals = new ArrayList<>();
   animals.add(new Animal());
   animals.add(new Animal());

   List<Pet> pets = new ArrayList<>();
   pets.add(new Pet());
   pets.add(new Pet());

   List<Cat> cats = new ArrayList<>();
   cats.add(new Cat());
   cats.add(new Cat());

   List<Dog> dogs = new ArrayList<>();
   dogs.add(new Dog());
   dogs.add(new Dog());

   iterateAnimals(animals);
   iterateAnimals(pets);
   iterateAnimals(cats);
   iterateAnimals(dogs);
}
ڪنسول آئوٽ:

Another iteration in the loop!
Another iteration in the loop!
Another iteration in the loop!
Another iteration in the loop!
Another iteration in the loop!
Another iteration in the loop!
Another iteration in the loop!
Another iteration in the loop!
اسان مجموعي طور تي 4 مجموعا ۽ 8 شيون ٺاھيون، ۽ ڪنسول تي بلڪل 8 داخلون آھن. هر شي عظيم ڪم ڪري ٿو! :) وائلڊ ڪارڊ اسان کي اجازت ڏني ته اسان کي آسانيءَ سان هڪ واحد طريقي سان مخصوص قسم سان جڙيل ضروري منطق کي درست ڪري سگھون. اسان هر قسم جي جانور لاءِ الڳ طريقو لکڻ جي ضرورت کي ختم ڪري ڇڏيو. تصور ڪريو ته اسان کي ڪيترا طريقا گهرجن ها جيڪڏهن اسان جي ايپليڪيشن زو يا جانورن جي آفيس طرفان استعمال ٿئي ها :) پر هاڻي اچو ته هڪ مختلف صورتحال تي نظر رکون. اسان جي وراثت جو درجو اڻڄاتل رهي ٿو: مٿين سطح جو طبقو آهي Animal، Petصرف هيٺئين طبقي سان، ۽ Catايندڙ Dogسطح تي طبقن سان. ھاڻي توھان کي ھن طريقي کي ٻيهر لکڻو پوندو iterateAnimals()ته جيئن ڪتن کان سواءِ ڪنھن به قسم جي جانور سان ڪم ڪري سگھجي . اهو آهي، ان کي قبول ڪرڻ گهرجي Collection<Animal>، Collection<Pet>يا Collection<Car>، پر ان سان ڪم نه ڪرڻ گهرجي Collection<Dog>. اسان اهو ڪيئن حاصل ڪري سگهون ٿا؟ اهو لڳي ٿو ته اسان ٻيهر هر قسم جي لاء هڪ الڳ طريقو لکڻ جي امڪان کي منهن ڏئي رهيا آهيون:/ ٻيو ڪيئن اسان مرتب ڪندڙ کي وضاحت ڪريون ٿا ته اسان ڇا ٿيڻ چاهيون ٿا؟ اهو اصل ۾ بلڪل سادو آهي! هڪ ڀيرو ٻيهر، وائلڊ ڪارڊ هتي اسان جي مدد لاء ايندا. پر هن ڀيري اسان هڪ ٻيو قسم جو وائلڊ ڪارڊ استعمال ڪنداسين - هڪ هيٺيون بائونڊڊ وائلڊ ڪارڊ ، جنهن جو اظهار ڪيو ويندو آهي super .
public static void iterateAnimals(Collection<? super Cat> animals) {

   for(int i = 0; i < animals.size(); i++) {

       System.out.println("Another iteration in the loop!");
   }
}
هتي اصول ساڳيو آهي. ٺاھ <? super Cat>ٺاھيندڙ کي ٻڌائي ٿو ته iterateAnimals()طريقو ان پٽ جي طور تي قبول ڪري سگھي ٿو ھڪڙي Catشئي جو مجموعو يا Catڪلاس جي ڪنھن اڳڪٿي کي ان پٽ طور. هن حالت ۾، Catڪلاس، ان جي والدين Pet، ۽ ان جي والدين جو والدين، Animal, سڀ هن وضاحت سان ملن ٿا. ڪلاس Dogاسان جي پابندي سان نه ٿو ملي، تنهنڪري هڪ دليل سان طريقو استعمال ڪرڻ جي ڪوشش جي List<Dog>نتيجي ۾ هڪ تاليف جي غلطي ٿيندي:
public static void main(String[] args) {

   List<Animal> animals = new ArrayList<>();
   animals.add(new Animal());
   animals.add(new Animal());

   List<Pet> pets = new ArrayList<>();
   pets.add(new Pet());
   pets.add(new Pet());

   List<Cat> cats = new ArrayList<>();
   cats.add(new Cat());
   cats.add(new Cat());

   List<Dog> dogs = new ArrayList<>();
   dogs.add(new Dog());
   dogs.add(new Dog());

   iterateAnimals(animals);
   iterateAnimals(pets);
   iterateAnimals(cats);

   // Compilation error!
   iterateAnimals(dogs);
}
اسان پنهنجو مسئلو حل ڪري ڇڏيو آهي، ۽ هڪ ڀيرو ٻيهر وائلڊ ڪارڊ انتهائي مفيد ثابت ٿيا آهن :) ان سان گڏ، سبق پڄاڻي تي پهتو آهي. ھاڻي توھان ڏسو ٿا ته توھان جي جاوا جي مطالعي ۾ ڪيڏا اھم عام آھن - اسان وٽ انھن بابت 4 مڪمل سبق آھن! پر هاڻي توهان موضوع ۾ چڱي طرح ماهر آهيو ۽ توهان نوڪري جي انٽرويو ۾ توهان جي صلاحيتن کي ثابت ڪري سگهو ٿا :) ۽ هاڻي، اهو وقت آهي ڪمن ڏانهن واپس وڃڻ جو! توهان جي پڙهائي ۾ بهترين ڪاميابي! :)
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION