Covariant Returtype i Java

1. Oversikt

I denne opplæringen skal vi se nærmere på den samvariante returtypen i Java. Før vi undersøker kovarians fra returtypens synspunkt, la oss se hva det betyr.

2. Kovarians

Kovarians kan betraktes som en kontrakt for hvordan en undertype aksepteres når bare supertypen er definert.

La oss se på et par grunnleggende eksempler på kovarians:

List integerList = new ArrayList (); Liste doubleList = ny ArrayList ();

kovarians betyr, vi kan få tilgang til spesifikke elementer definert via deres supertype. Derimot, vi har ikke lov til å sette elementer i et kovariant system, siden kompilatoren ikke klarte å bestemme den faktiske typen generisk struktur.

3. Covariant Returtype

De kovariant returtype er - når vi overstyrer en metode - det som gjør at returtypen kan være undertypen til typen av den overstyrte metoden.

For å gjennomføre dette, la oss ta en enkel Produsent klasse med en produsere() metode. Som standard returnerer den a String som en Gjenstand å gi fleksibilitet for barneklasser:

public class Producer {public Object produce (String input) {Object result = input.toLowerCase (); returresultat; }}

Som et resultat av Gjenstand som returtype kan vi ha en mer konkret returtype i barneklassen. Det vil være den kovariante returtypen og vil produsere tall fra tegnsekvenser:

offentlig klasse IntegerProducer utvider produsent {@ Override public Integer produce (String input) {return Integer.parseInt (input); }}

4. Bruk av strukturen

Hovedideen bak de kovariante returtypene er å støtte Liskov-erstatningen.

La oss for eksempel vurdere følgende produsentscenario:

@Test offentlig ugyldig nårInputIsArbitrary_thenProducerProducesString () {String arbitraryInput = "bare en tilfeldig tekst"; Produsentprodusent = ny produsent (); Objekt objectOutput = producer.produce (arbitraryInput); assertEquals (arbitraryInput, objectOutput); assertEquals (String.class, objectOutput.getClass ()); }

Etter å ha byttet til IntegerProducer, kan forretningslogikken som faktisk gir resultatet forbli den samme:

@Test offentlig ugyldig nårInputIsSupported_thenProducerCreatesInteger () {String integerAsString = "42"; Produsentprodusent = ny IntegerProducer (); Objektresultat = produsent.produsere (heltallAsString); assertEquals (Integer.class, result.getClass ()); assertEquals (Integer.parseInt (integerAsString), resultat); }

Imidlertid refererer vi fremdeles til resultatet via en Gjenstand. Hver gang vi begynner å bruke en eksplisitt referanse til HeltallProdusent, vi kan hente resultatet som en Heltall uten downcasting:

@Test offentlig ugyldig nårInputIsSupported_thenIntegerProducerCreatesIntegerWithoutCasting () {String integerAsString = "42"; IntegerProducer produsent = ny IntegerProducer (); Heltalsresultat = produsent.produsere (integerAsString); assertEquals (Integer.parseInt (integerAsString), resultat); }

Et kjent scenario er Gjenstand#klone metode, som returnerer en Gjenstand som standard. Hver gang vi overstyrer klone () metode, lar anlegget av samvariante returtyper oss ha et mer konkret returobjekt enn Gjenstand seg selv.

5. Konklusjon

I denne artikkelen så vi hva typene kovarians og kovariant retur er, og hvordan de oppfører seg i Java.

Som alltid er koden tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found