Tip kovarijantnog povratka u Javi

1. Pregled

U ovom uputstvu detaljnije ćemo pogledati kovarijantni tip povratka u Javi. Prije ispitivanja kovarijancije s gledišta tipa return, pogledajmo što to znači.

2. Kovarijancija

Kovarijancija se može smatrati ugovorom o prihvaćanju podtipa kada je definiran samo supertip.

Razmotrimo nekoliko osnovnih primjera kovarijancije:

Popis integerList = novi ArrayList (); Popis doubleList = novi ArrayList ();

Takokovarijancija znači da možemo pristupiti određenim elementima definiranim putem njihovog nadtipa. Međutim, ne smijemo stavljati elemente u kovarijantni sustav, budući da prevoditelj ne bi uspio odrediti stvarni tip generičke strukture.

3. Kovarijantni povratni tip

The kovarijantni tip povratka je - kada nadjačavamo metodu - što omogućuje da tip povratka bude podtip tipa nadjačane metode.

Da bismo to primijenili u praksi, uzmimo jednostavan Proizvođač razred s a proizvesti () metoda. Po defaultu vraća a Niz kao an Objekt pružiti fleksibilnost za nastavu djeteta:

javna klasa Producer {javni objektni proizvod (unos niza) {Rezultat objekta = input.toLowerCase (); povratni rezultat; }}

Kao rezultat Objekt kao povratni tip možemo imati konkretniji povratni tip u podređenoj klasi. To će biti kovarijantni povratni tip i stvorit će brojeve iz sekvenci znakova:

javna klasa IntegerProducer proširuje Producer {@Preuzmi javni Integer proizvod (String input) {return Integer.parseInt (input); }}

4. Korištenje strukture

Glavna ideja koja stoji iza kovarijantnih vrsta povratka je podržati zamjenu Liskova.

Na primjer, razmotrimo sljedeći scenarij proizvođača:

@Test public void whenInputIsArbitrary_thenProducerProducesString () {String arbitraryInput = "samo slučajni tekst"; Producent producent = novi producent (); Objekt objectOutput = proizvođač.produce (proizvoljanInput); assertEquals (proizvoljanInput, objectOutput); assertEquals (String.class, objectOutput.getClass ()); }

Nakon promjene u IntegerProducer, poslovna logika koja zapravo donosi rezultat može ostati ista:

@Test public void whenInputIsSupported_thenProducerCreatesInteger () {String integerAsString = "42"; Proizvođač proizvođač = novi IntegerProducer (); Rezultat objekta = proizvođač.produce (integerAsString); assertEquals (Integer.class, result.getClass ()); assertEquals (Integer.parseInt (integerAsString), rezultat); }

Međutim, i dalje referenciramo rezultat putem Objekt. Kad god počnemo koristiti eksplicitnu referencu na IntegerProducer, rezultat možemo dobiti kao Cijeli broj bez spuštanja:

@Test public void whenInputIsSupported_thenIntegerProducerCreatesIntegerWithoutCasting () {String integerAsString = "42"; Proizvođač IntegerProducer = novi IntegerProducer (); Cjelobrojni rezultat = proizvođač.produce (integerAsString); assertEquals (Integer.parseInt (integerAsString), rezultat); }

Poznati scenarij je Objekt#klon metoda koja vraća Objekt prema zadanim postavkama. Kad god prevalimo klon() metoda, mogućnost kovarijantnih vrsta povratka omogućuje nam da imamo konkretniji povratni objekt od Objekt sebe.

5. Zaključak

U ovom smo članku vidjeli što su kovarijancija i kovarijantni povratni tipovi i kako se ponašaju u Javi.

Kao i uvijek, kôd je dostupan na GitHub-u.