JavaRush /Java Blog /Random-TK /Java Generics-de ýabany kartalar

Java Generics-de ýabany kartalar

Toparda çap edildi
Salam! Generika mowzugyny öwrenmegi dowam etdirýäris. Öňki leksiýalardan ( generikler bilen işlän wagtyňyz vararglary ulanmak we görnüşi pozmak barada) eýýäm olar hakda gowy bilimiňiz bar , ýöne entek bir möhüm mowzugy açmadyk: wikard kartoçkalary . Bu generikleriň örän möhüm aýratynlygy. Şeýle bir köp welin, munuň üçin aýratyn leksiýa bagyş etdik! Şeýle-de bolsa, kartoçkalarda çylşyrymly zat ýok, indi görersiňiz :) Generikdäki kartoçkalar - 1Geliň, bir meselä seredeliň:
public class Main {

   public static void main(String[] args) {

       String str = new String("Test!");
       // ниHowих проблем
       Object obj = str;

       List<String> strings = new ArrayList<String>();
       // ошибка компиляции!
       List<Object> objects = strings;
   }
}
Bu ýerde näme bolýar? Iki sany meňzeş ýagdaýy görýäris. StringBularyň birinjisinde, ýazmak üçin bir zat zyňmaga synanyşýarys Object. Munuň bilen baglanyşykly hiç hili mesele ýok, hemme zat bolmalysy ýaly işleýär. Emma ikinji ýagdaýda düzüji ýalňyşlyk goýberýär. Edil şol bir zady edýäne meňzeýänem bolsa. Diňe indi birnäçe obýektiň ýygyndysyny ulanýarys. Emma näme üçin ýalňyşlyk ýüze çykýar? StringBir obýekti bir görnüşe ýa-da 20 jisime atsak-da, tapawudy näme Object? Bir obýekt bilen obýektleriň ýygyndysynyň arasynda möhüm tapawut bar . Bir synp Bsynpyň mirasdüşeri bolsa А, Collection<B>onda ol mirasdüşer däl Collection<A>. Hut şu sebäpdenem özümizi getirip List<String>bilmedik List<Object>. Stringmirasdüşer Object, ýöne List<String>mirasçy däl List<Object>. Göçme manyda Bu gaty mantykly görünmeýär. Näme üçin dili döredijiler bu ýörelge bilen ugrukdyryldy? Düzüjiniň bu ýerde bize ýalňyşlyk bermejekdigini göz öňüne getireliň:
List<String> strings = new ArrayList<String>();
List<Object> objects = strings;
Bu ýagdaýda, mysal üçin, aşakdakylary edip bileris:
objects.add(new Object());
String s = strings.get(0);
Düzediji bize ýalňyşlyklar bermedi we List<Object> objectsetirler ýygyndysyna salgylanma döretmäge mümkinçilik berendigi sebäpli, setir däl-de, islendik obýekt stringsgoşup bileris ! Şeýlelik bilen, kolleksiýamyzda diňe umumylykda görkezilen zatlar bar diýen kepilligi ýitirdik . Genagny, generikleriň esasy artykmaçlygyny - görnüşli howpsuzlygy ýitirdik. Düzediji bu zatlaryň hemmesini etmäge rugsat berenligi sebäpli, diňe programma ýerine ýetirilende ýalňyşlyk aljakdygymyzy aňladýar, bu bolsa hemişe düzmek ýalňyşlygyndan has erbetdir. Şeýle ýagdaýlaryň öňüni almak üçin düzüji bize ýalňyşlyk berýär: stringsObjectString
// ошибка компиляции
List<Object> objects = strings;
List<String>... we mirasdüşer däldigini ýatladýar List<Object>. Bu, generikleriň işlemegi üçin demirden ýasalan düzgün we olary ulananyňyzda ýatda saklamaly. Geliň dowam edeliň. Kiçijik synp iýerarhiýamyz bar diýeliň:
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()");
   }
}
Iýerarhiýanyň başynda diňe Haýwanlar bar: Haýwanlar olardan miras galypdyr. Öý haýwanlary 2 görnüşe bölünýär - Itler we pişikler. Indi ýönekeý bir usul döretmelidigimizi göz öňüne getiriň iterateAnimals(). Usul islendik haýwanlaryň ýygyndysyny (,,,) kabul etmeli Animal, ähli elementleri gaýtalamaly we her gezek konsola bir zat çykarmaly. Geliň, bu usuly ýazmaga synanyşalyň: PetCatDog
public static void iterateAnimals(Collection<Animal> animals) {

   for(Animal animal: animals) {

       System.out.println("Еще один шаг в цикле пройден!");
   }
}
Mesele çözülen ýaly! Şeýle-de bolsa, ýaňy-ýakynda bilşimiz ýaly List<Cat>ýa-da mirasçy List<Dog>däl ! Şol sebäpden, pişikleriň sanawy bolan bir usuly çagyrjak bolanymyzda , düzüjiniň ýalňyşlygyny alarys: 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("Еще один шаг в цикле пройден!");
       }
   }

   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());

       //ошибка компилятора!
       iterateAnimals(cats);
   }
}
Usagdaý biziň üçin gowy görünmeýär! Görnüşi ýaly, haýwanlaryň ähli görnüşlerini sanamak üçin aýratyn usullar ýazmaly bolarysmy? Aslynda, ýok, hökman däl :) We kartoçkalar bu meselede bize kömek eder ! Meseläni aşakdaky gurluşyklary ulanyp, ýönekeý bir usul bilen çözeris:
public static void iterateAnimals(Collection<? extends Animal> animals) {

   for(Animal animal: animals) {

       System.out.println("Еще один шаг в цикле пройден!");
   }
}
Bu ýabany kartoçka. Has takygy, bu kartoçkanyň birnäçe görnüşiniň ilkinjisi - “ uzalýar ” (başga bir ady “ Upper Bounded Wildcards” ). Bu dizaýn bize näme diýýär? AnimalBu usulyň islendik nesil synpynyň obýektleriniň ýa-da obýektleriniň ýygyndysy hökmünde kabul edilýändigini aňladýar Animal (? extends Animal). AnimalBaşgaça aýdylanda, usul kolleksiýany Petýa Dog-da giriş hökmünde kabul edip biler Cat- tapawudy ýok. Munuň işleýändigine göz ýetireliň:
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);
}
Konsol çykyşy:

Еще один шаг в цикле пройден!
Еще один шаг в цикле пройден!
Еще один шаг в цикле пройден!
Еще один шаг в цикле пройден!
Еще один шаг в цикле пройден!
Еще один шаг в цикле пройден!
Еще один шаг в цикле пройден!
Еще один шаг в цикле пройден!
Jemi 4 kolleksiýa we 8 obýekt döretdik, konsolda takmynan 8 ýazgy bar. Hemme zat gowy işleýär! :) “Wildcard”, belli bir görnüşleri baglanyşdyrmak bilen zerur logikany aňsatlyk bilen sazlamaga mümkinçilik berdi. Haýwanlaryň her görnüşi üçin aýratyn usul ýazmak zerurlygyndan halas bolduk. Programmamyz haýwanat bagynda ýa-da weterinariýa hassahanasynda ulanylan bolsa, näçe usul ulanjakdygymyzy göz öňüne getiriň :) Indi başga bir ýagdaýa seredeliň. Miras iýerarhiýamyz öňküligine galar: iň ýokary derejeli synp Animal, aşakda öý haýwanlary synpy Pet, indiki derejede bolsa Catwe Dog. Indi itden başgairetateAnimals() haýwanlaryň islendik görnüşi bilen işlemegi üçin usuly täzeden ýazmaly . .Agny, kabul etmeli ýa -da giriş hökmünde , ýöne işlemeli däl . Muny nädip gazanyp bileris? Her görnüş üçin aýratyn usul ýazmak umydy ýene-de öňümizde duran ýaly: / Kompýuterimize logikamyzy başga nädip düşündirip bileris? Bu gaty ýönekeý edilip bilner! Bu ýerde ýabany kartoçkalar ýene bize kömek eder. Thisöne bu gezek başga bir görnüşi ulanarys - “ super ” (başga bir ady “ Lower Bounded Wildcards ”). Collection<Animal>Collection<Pet>Collection<Cat>Collection<Dog>
public static void iterateAnimals(Collection<? super Cat> animals) {

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

       System.out.println("Еще один шаг в цикле пройден!");
   }
}
Principleörelge bu ýerde meňzeýär. Gurluşyk <? super Cat>düzüjä bu usulyň synpyň ýa-da beýleki ata-babalar synpynyň iterateAnimals()obýektleriniň ýygyndysyny giriş hökmünde alyp biljekdigini aýdýar . Biziň ýagdaýymyzda synpyň özi , atasy we atasynyň atasy - bu düşündirişe laýyk gelýär . Synp bu çäklendirmä laýyk gelmeýär we şonuň üçin sanaw bilen bir usuly ulanmaga synanyşmak, jemleme ýalňyşlygyna sebäp bolar: CatCatCatPetsAnimalDogList<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);

   //ошибка компиляции!
   iterateAnimals(dogs);
}
Meselämiz çözüldi we ýene-de kartoçkalar gaty peýdaly boldy :) Bu leksiýany tamamlaýar. Indi Java öwrenilende umumylyk mowzugynyň nähili möhümdigini görýärsiňiz - biz oňa 4 leksiýa geçirdik! Nowöne indi mowzugy gowy bilýärsiňiz we söhbetdeşlikde özüňizi subut edip bilersiňiz :) Indi bolsa wezipelere gaýdyp gelmegiň wagty geldi! Okuwyňyzda üstünlik arzuw ediň! :)
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION