Základy genericity
V tomto článku si povieme niečo málo o genericitě a prečo ju používať. Tento článok nebude obsahovať celú problematiku, ale len časť z nej. Syntax je podobná ako u kolekcií.
V každom zložitejším programe môžu vznikať chyby, ktoré sa zle hľadajú. Vznikajú väčšinou úplne niekde inde ako bol ich zdroj začiatku. Genericita zlepšuje stabilitu kódu, pretože umožňuje detekovať viac chýb pri preklade.
Najskôr si ukážeme kód bez genericity ...
public class Box{ private Object object; public void pridat(Object object){ this.object=object; } public Object zjistit(){ return object; } }
public class BoxDemo{ public static void main(String[]args){ Box schrankaSCisly=new Box(); schrankaSCisly.pridat("10"); //pridavam string i kdyz je schránka určena nečemu jinému Integer cislo=(Integer)schrankaSCisly.zjistit(); //chci cislo typu Int System.out.println(cislo); } }
V takomto prípade prekladač nič nehlási a chyba sa zobrazí až pri behu programu kedy havaruje s výnimkou ClassCastException. Keby tu bola genericita, chyba by sa už hlásila pri preklade.
Teraz si tento príklad napíšeme s genericitou.
public class Box<T>{ private T t; //T oznacuje typ public void pridat(T t){ this.t=t; } public T zjistit(){ return t; } }
public class BoxDemo2{ public static void main(String[]args){ Box<Integer>schrankaSCisly=new Box<Integer>; schrankaSCisly.pridat(new Integer(10)); Integer cislo=schrankaSCisly.zjistit(); //nemusime pouzit pretypovani } }
V tomto príklade je schránka len pre celočíselný typ. Ak sa pokúsime doň dávať niečo iné, napr. String, prekladač zahlási chybu.
Tu je zoznam bežne používaných typov:
Parametre typu:
- E - element (používa sa pri kolekciách)
- K - key
- N - number
- T - typ
- V - value
- S, U, V atď. Ďalšie typy
Menšie ukážka:
//mame oddeleni ve firme kde muzou byt zamestnanci interface Oddeleni<E> extends Collection<E>; //grafik je jeden ze zamestnancu interface Grafik extends Zamestnanec{} Grafik grafik=...; //potrebujeme zamestnance ktereho "pasujeme" na grafika Zamestnanec a=grafik; //a samozrejme pro grafiky muzeme vytvorit oddeleni Oddeleni<Grafik>oddeleniGrafiku=...; oddeleniGrafiku.pridat(grafik); //do takoveho oddeleni nemuzeme pridat nikoho jineho =) //pokud vytvorime toto Oddeleni<Zamestnanec>oddeleni=...; //tak sem nemuzeme pridavat ostatni zamestnance, uz jenom z toho duvodu ze se vsichni spolu nesnesou (napr. grafici s programatorama :D) //teoreticky muzete ale byl by v tom bordel oddeleni=oddeleniGrafiku; //chyba
Existuje taky zástupný znak, ktorý sa značí takto: <?>
//mame nejake oddeleni zamestnancu Oddeleni<? extends Zamestanec> oddeleni=...; //takze muzeme vytvorit oddeleni grafiku a udelat pak toto oddeleni=oddeleniGrafiku; //jenze nemuzeme pridavat dalsi zamestnance ale muzeme napriklad vyplacet oddeleni jednotlive void vyplatitZamestnance(Oddeleni<? extends Zamestnanec>oddeleni){ for(Zamestnanec a: oddeleni){ a.vyplatit; } }
Snáď som vám načrtol o čo ide a pochopili ste aspoň časť z toho.