Generički konstruktori u Javi
1. Pregled
Prethodno smo razgovarali o osnovama Java Generics-a. U ovom uputstvu ćemo pogledati Generičke konstruktore u Javi.
Generički konstruktor je konstruktor koji ima barem jedan parametar generičkog tipa.
Vidjet ćemo da generički konstruktori ne moraju biti u generičkoj klasi, a ne moraju svi konstruktori u generičkoj klasi biti generički.
2. Neuobičajena klasa
Prvo, imamo jednostavnu nastavu Ulazak, koji nije generička klasa:
ulazak u javnu klasu {podaci privatnog niza; privatni int čin; }
U ovu ćemo klasu dodati dva konstruktora: osnovni konstruktor s dva parametra i generički konstruktor.
2.1. Osnovni konstruktor
Prvi Ulazak konstruktor je jednostavan konstruktor s dva parametra:
javni unos (podaci niza, int rank) {this.data = podaci; this.rank = rank; }
Sada, upotrijebimo ovaj osnovni konstruktor za stvaranje Ulazak objekt:
@Test javna praznina givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK () {Entry entry = new Entry ("sample", 1); assertEquals ("uzorak", entry.getData ()); assertEquals (1, entry.getRank ()); }
2.2. Generički konstruktor
Dalje, naš drugi konstruktor je generički konstruktor:
javni unos (E element) {this.data = element.toString (); this.rank = element.getRank (); }
iako Ulazak klasa nije generička, ona ima generički konstruktor, jer ima parametar element tipa E.
Generički tip E je ograničen i trebao bi provoditi oboje Rankable i Serijalizirati sučelja.
Pogledajmo sada Rankable sučelje, koje ima jednu metodu:
javno sučelje Rankable {public int getRank (); }
I, pretpostavimo da imamo nastavu Proizvod koja provodi Rankable sučelje:
proizvod javne klase implementira Rankable, Serializable {ime privatnog niza; privatna dvostruka cijena; privatna int prodaja; javni proizvod (naziv niza, dvostruka cijena) {this.name = name; this.price = cijena; } @Override public int getRank () {povrat prodaje; }}
Tada možemo koristiti generički konstruktor za stvaranje Ulazak predmeti koji koriste a Proizvod:
@Test javna praznina givenGenericConstructor_whenCreateNonGenericEntry_thenOK () {Proizvod proizvoda = novi proizvod ("mlijeko", 2.5); product.setSales (30); Unos unosa = novi unos (proizvod); assertEquals (product.toString (), entry.getData ()); assertEquals (30, entry.getRank ()); }
3. Generička klasa
Dalje ćemo pogledati generičku klasu pod nazivom GenericEntry:
javna klasa GenericEntry {privatni T podaci; privatni int čin; }
Također ćemo dodati iste dvije vrste konstruktora kao i prethodni odjeljak u ovu klasu.
3.1. Osnovni konstruktor
Prvo, napišimo jednostavan, generički konstruktor za naš GenericEntry razred:
javni GenericEntry (int rank) {this.rank = rank; }
Čak iako GenericEntry je generička klasa, ovo je jednostavan konstruktor koji nema parametar generičkog tipa.
Sada ovaj konstruktor možemo koristiti za stvaranje a GenericEntry:
@Test javna praznina givenNonGenericConstructor_whenCreateGenericEntry_thenOK () {GenericEntry entry = new GenericEntry (1); assertNull (entry.getData ()); assertEquals (1, entry.getRank ()); }
3.2. Generički konstruktor
Dalje, dodajmo drugi konstruktor u našu klasu:
javni GenericEntry (T podaci, int rank) {this.data = podaci; this.rank = rank; }
Ovo je generički konstruktor, jer ima podaci parametar generičkog tipa T. Imajte na umu da ne trebamo dodavati u deklaraciji konstruktora, jer je implicitno tamo.
Sada, testirajmo naš generički konstruktor:
@Test javna praznina givenGenericConstructor_whenCreateGenericEntry_thenOK () {GenericEntry entry = new GenericEntry ("sample", 1); assertEquals ("uzorak", entry.getData ()); assertEquals (1, entry.getRank ()); }
4. Generički konstruktor različite vrste
U našoj generičkoj klasi također možemo imati konstruktor s generičkim tipom koji se razlikuje od generičkog tipa klase:
javni GenericEntry (E element) {this.data = (T) element; this.rank = element.getRank (); }
Ovaj GenericEntry konstruktor ima parametar element s tipom E, koji se razlikuje od T tip. Pogledajmo na djelu:
@Test javna praznina givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK () {Proizvod proizvoda = novi proizvod ("mlijeko", 2.5); product.setSales (30); Unos GenericEntry = novi GenericEntry (proizvod); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }
Imajte na umu da:
- U našem smo primjeru koristili Proizvod (E) za stvaranje a GenericEntry tipa Serijalizirati (T)
- Ovaj konstruktor možemo koristiti samo kada je parametar type E može se baciti na T
5. Više generičkih vrsta
Dalje, imamo generički razred MapEntry s dvije generičke vrste:
javna klasa MapEntry {privatni K ključ; privatna V vrijednost; javni MapEntry (ključ K, vrijednost V) {this.key = key; this.value = vrijednost; }}
MapEntry ima jedan generički konstruktor s dva parametra, svaki različitog tipa. Upotrijebimo ga u jednostavnom jediničnom testu:
@Test javna praznina givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK () {MapEntry entry = new MapEntry ("uzorak", 1); assertEquals ("uzorak", entry.getKey ()); assertEquals (1, entry.getValue (). intValue ()); }
6. Zamjenski znakovi
Napokon, možemo koristiti zamjenske znakove u generičkom konstruktoru:
javni GenericEntry (nije obavezno) {if (nije obavezno.isPresent ()) {this.data = (T) nije obavezno.get (); this.rank = neobvezno.get (). getRank (); }}
Evo, u tome smo koristili zamjenske znakove GenericEntry konstruktor za vezanje Neobvezno tip:
@Test javna praznina givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK () {Proizvod proizvoda = novi proizvod ("mlijeko", 2.5); product.setSales (30); Neobvezno neobavezno = Neobvezno.of (proizvod); Unos GenericEntry = novi GenericEntry (nije obavezno); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }
Imajte na umu da bismo trebali moći emitirati opcijski tip parametra (u našem slučaju, Proizvod) prema GenericEntry vrsta (u našem slučaju, Serijalizirati).
7. Zaključak
U ovom smo članku naučili kako definirati i koristiti generičke konstruktore i u generičkim i u generičkim klasama.
Cjeloviti izvorni kod možete pronaći na GitHubu.