11 GENERIKE KLASE 1 generike klase su klase

  • Slides: 25
Download presentation
11 GENERIČKE KLASE 1

11 GENERIČKE KLASE 1

 • generičke klase su klase parametrizovane drugim klasama • predstavljaju vid parametarskog polimorfizma

• generičke klase su klase parametrizovane drugim klasama • predstavljaju vid parametarskog polimorfizma • u javi su realizovane osloncem na jedinstvenu hijerarhiju klasa, a posebno na činjenicu da sve klase nasleđuju klasu Object 2

kako funkcioniše generičnost? • klasu koja se ponaša kao da je parametrizovana klasom T

kako funkcioniše generičnost? • klasu koja se ponaša kao da je parametrizovana klasom T realizujemo tako što – na mestu gde bi trebalo da se pojavi generički parametar T stavljamo klasu Object – u klijentu koristimo inkluzioni polimorfizam ili koercitivni polimorfizam (kast) za konverziju iz Object u konkretnu klasu, tj. generički argument • ovako definisana klasa ponaša se kao generička klasa i to je dugo bio jedini način za realizaciju generičnosti u javi 3

public class Gen. Class { Object f; public Gen. Class(Object f) { this. f

public class Gen. Class { Object f; public Gen. Class(Object f) { this. f = f; } public void setf(Object f) { this. f = f; } public Object getf() { return f; } } Object igra ulogu generičkog parametra 4

 • klijent: Gen. Class g = new Gen. Class("Objekat kreiran"); g. setf("Polje f

• klijent: Gen. Class g = new Gen. Class("Objekat kreiran"); g. setf("Polje f setovano"); inkluzioni polimorfizam String s = (String)g. getf(); koercija • u ovom klijentu, klasa Gen. Class ponaša se kao generička klasa sa generičkim argumentom String 5

sintaksa • definiše se sa class Ime. Klase<P 1, . . . , Pn>

sintaksa • definiše se sa class Ime. Klase<P 1, . . . , Pn> { //genericki parametri mogu se upotrebiti //za tip polja, tip metode i tip parametra //metode } gde je modifikator ili public ili default (tj. prazan), a P 1, . . . , Pn su generički parametri 6

public class Gen. Class<T> { T f; public Gen. Class(T f) { this. f

public class Gen. Class<T> { T f; public Gen. Class(T f) { this. f = f; } public void setf(T f) { this. f = f; } public T getf() { return f; } } T je generički parametar 7

instanciranje i korišćenje • generička klasa se instancira tako što se uz ime obavezno

instanciranje i korišćenje • generička klasa se instancira tako što se uz ime obavezno navode generički argumenti: poziv konstruktora Gen. Class<String> g; g = new Gen. Class<String>("Objekat kreiran"); • za korišćenje nije potrebna koercija: String s = g. getf(); ne treba (String) 8

UML <P 1, . . . , Pn> Gen. Klasa generički parametri Gen. Klasa<A

UML <P 1, . . . , Pn> Gen. Klasa generički parametri Gen. Klasa<A 1, . . . , An> <<bind>><A 1, . . . , An> generički argumenti Konk. Klasa veza korišćenja sa stereotipom bind prvi način drugi način 9

ograničavanje gen. parametra • svaki generički parametar može se ograničiti natklasom: class Ime. Klase<P

ograničavanje gen. parametra • svaki generički parametar može se ograničiti natklasom: class Ime. Klase<P extends T> {. . . . } • prilikom konkretizacije, generički argument može biti samo klasa T ili neka klasa koja je nasleđuje! 10

džokerski generički parametar (wildcard) • označava se sa ? • upotrebljava se za oznaku

džokerski generički parametar (wildcard) • označava se sa ? • upotrebljava se za oznaku tipa promenljivih i/ili parametara metode kada se zna da su generički, ali se ne zna konkretizacija (tj. ne znaju se generički argumenti tih tipova) • drugim rečima, generička klasa sa džokerskim argumentom ponaša se kao čist generički tip • između generičke klase sa džokerkim argumentom i konkretizovane generičke klase postoji odnos sličan inkluzionom polimorfizmu 11

primer • metoda met ima za parametar tip Gen. Class: public void met(Gen. Class<?

primer • metoda met ima za parametar tip Gen. Class: public void met(Gen. Class<? > par) {…} metoda se može pozvati sa argumentom čiji je tip bilo koja konkretizacija klase Gen. Class • razlog: ako bi se upotrebio identifikator, prevodilac ne bi znao da li se identifikator odnosi na bilo koju klasu ili na neku konkretnu klasu P može biti konkretna klasa sa tim nazivom • dakle, ne public void met(Gen. Class<P> par) {…} 12

još jedan primer • Lista je u javi realizovana kao gotova generička klasa sa

još jedan primer • Lista je u javi realizovana kao gotova generička klasa sa nazivom Linked. List<T> podseća na dodelu potomka pretku • Iskazom Linked. List<? > lst = new Linked. List<String>(); promenljiva lst dobija tip Linked. List<String> što se obezbeđuje u toku prevođenja 13

 • Džokerski generički parametar može se ograničiti "odozgo" iskazom Gen. Class<? extends K>

• Džokerski generički parametar može se ograničiti "odozgo" iskazom Gen. Class<? extends K> a može se ograničiti i "odozdo" iskazom Gen. Class<? super M> • u prvom slučaju generički argument pripada klasi K ili nekom njenom potomku, a u drugom pripada nekoj natklasi klase M (ali ne može biti M) 14

generičke metode • statički članovi klase ne mogu koristiti generičke parametre klase, ali •

generičke metode • statički članovi klase ne mogu koristiti generičke parametre klase, ali • svaka metoda, nestatička ili statička (uključujući i konstruktore) može imati sopstvene generičke parametre koji su nezavisni od generičkih parametara klase: static <U, V extends U> int met(U x, V[] y) {…} <P> konstruktor(P a) {…} • napomena: pri pozivu, argumenti generičke metode se ne navode 15

Sirovi tipovi (Raw Types) • jesu način za upotrebu generičkih klasa koji povezuje stari

Sirovi tipovi (Raw Types) • jesu način za upotrebu generičkih klasa koji povezuje stari i novi način realizacije • koriste se tako što se generička klasa koristi bez navođenja generičkih argumenata Gen. Class s. Ob = new Gen. Class("ovo je string"); • prilikom korišćenja mora se vršiti koercija: String str = (String)s. Ob. getf(); što je, u stvari, stari način korišćenja generičnosti 16

Brisanje (erasing) • postupak za povezivanje sintakse generičnosti sa stvarnom realizacijom (baziranom na jedinstvenoj

Brisanje (erasing) • postupak za povezivanje sintakse generičnosti sa stvarnom realizacijom (baziranom na jedinstvenoj hijerarhiji klasa) • izvodi se u toku prevođenja tako što – pre izrade bajt-koda, svaki generički parametar biva zamenjen najbližom konkretnom natklasom; ako parametar nema gornju granicu, zamenjuje se sa Object, a ako je ima, zamenjuje se (konkretnom) gornjom granicom – pri obraćanju metodama sa generičkim rezultatom, dodaje se operator konverzije 17

public class Gen. Class<T> { T f; public Gen. Class(T f) { this. f

public class Gen. Class<T> { T f; public Gen. Class(T f) { this. f = f; } public void setf(T f) { this. f = f; } public T getf() { return f; } } T se zamenjuje sa Object posle brisanja postaje public class Gen. Class extends Object { Object f; public Gen. Class(Object f) { this. f = f; } public void setf(Object f) { this. f = f; } public Object getf() { return f; } } 18

 • Slično, u klasi public class Genericka. Klasa<P extends Konkr. Klasa> { ……………….

• Slično, u klasi public class Genericka. Klasa<P extends Konkr. Klasa> { ………………. P se zamenjuje sa Konkr. Klasa } svaka pojava P zamenjuje se sa Konkr. Klasa • Obraćanje metodi što vraća generički tip ili polju generičkog tipa snabdeva se operatorom kasta: Gen. Class<String> obs = new Gen. Class<String>("ovo je string"); ………………. String s = obs. getf(); zamenjuje se sa String s = (String)obs. getf(); • Sledi da je najveća prednost posebne sintakse činjenica da se kastovanje vrši automatski! 19

Nasleđivanje • generičke klase mogu se povezivati nasleđivanjem, pri čemi potklasa prosleđuje konkretne generičke

Nasleđivanje • generičke klase mogu se povezivati nasleđivanjem, pri čemi potklasa prosleđuje konkretne generičke argumente natklasi • negenerička klasa može imati generičku potklasu 20

Operator instanceof • primenljiv je i na generičke klase, ali sa džokerskim generičkim argumentom

Operator instanceof • primenljiv je i na generičke klase, ali sa džokerskim generičkim argumentom • dakle, dozvoljeno je pisati DA ob instanceof Gen. Class<? > s tim što će operacija vratiti true ako sam objekat pripada bilo kojoj konkretizaciji Gen. Class. • nije dozvoljeno pisati NE ob instanceof Gen. Class<String> i to zbog brisanja 21

Ograničenja • Klase koje su generički parametri ne mogu se instancirati unutar generičke klase

Ograničenja • Klase koje su generički parametri ne mogu se instancirati unutar generičke klase (razumljivo) • Statičke metode ne mogu koristiti generičke parametre, ali mogu imati sopstvene • Poseban problem čine nizovi koji su, sami po sebi generički 22

Ograničenja kod nizova • ne može se definisati niz generičkih referenci NE zadatog tipa:

Ograničenja kod nizova • ne može se definisati niz generičkih referenci NE zadatog tipa: Gen. Class<String>[] g = new Gen. Class<String> [100]; ali se može upotrebiti džokerski argument: Gen. Class<? >[] g = new Gen. Class<? > [100]; DA • u drugom slučaju biće stvoren niz referenci tipa Object 23

 • polje tipa niza generičkih vrednosti može se definisati, ali se ne može

• polje tipa niza generičkih vrednosti može se definisati, ali se ne može instancirati public class H<P> { DA P[] values; public H() { NE values = new P[200]; } …………………. } 24

 • rešenje: proslediti niz kao parametar konstruktora public class H<P> { P[] values;

• rešenje: proslediti niz kao parametar konstruktora public class H<P> { P[] values; public H(P[] values) { DA this. values = values; } ………………. } 25