Covariant Returtype i Java

1. Oversigt

I denne vejledning skal vi se nærmere på den covariante returtype i Java. Inden vi undersøger kovarians set fra returtypens synspunkt, skal vi se, hvad det betyder.

2. Kovarians

Kovarians kan betragtes som en kontrakt for, hvordan en undertype accepteres, når kun supertypen er defineret.

Lad os overveje et par grundlæggende eksempler på kovarians:

Liste over heltalListe = ny ArrayList (); Liste doubleList = ny ArrayList ();

kovarians betyder, at vi kan få adgang til specifikke elementer defineret via deres supertype. Imidlertid, vi har ikke lov til at placere elementer i et covariant system, da kompilatoren ikke kunne bestemme den faktiske type af den generiske struktur.

3. Covariant Returtype

Det covariant returtype er - når vi tilsidesætter en metode - hvad gør det muligt for returtypen at være undertype for typen af ​​den tilsidesatte metode.

For at omsætte dette i praksis, lad os tage en simpel Producent klasse med en fremstille() metode. Som standard returnerer den a Snor som en Objekt at give børneklasser fleksibilitet:

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

Som et resultat af Objekt som returtype kan vi have en mere konkret returtype i barneklassen. Det vil være den kovariante returtype og vil producere tal fra tegnsekvenser:

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

4. Anvendelsen af ​​strukturen

Hovedideen bag de kovariante returtyper er at støtte Liskov-udskiftningen.

Lad os for eksempel overveje følgende producentscenarie:

@Test offentligt ugyldigt nårInputIsArbitrary_thenProducerProducesString () {String arbitraryInput = "bare en tilfældig tekst"; Producentproducent = ny producent (); Objekt objectOutput = producer.produce (arbitraryInput); assertEquals (arbitraryInput, objectOutput); assertEquals (String.class, objectOutput.getClass ()); }

Efter skift til IntegerProducer, den forretningslogik, der faktisk producerer resultatet, kan forblive den samme:

@Test offentlig ugyldigt nårInputIsSupported_thenProducerCreatesInteger () {String integerAsString = "42"; Producentproducent = ny IntegerProducer (); Objektresultat = producer.produce (integerAsString); assertEquals (Integer.class, result.getClass ()); assertEquals (Integer.parseInt (integerAsString), resultat); }

Imidlertid henviser vi stadig til resultatet via en Objekt. Hver gang vi begynder at bruge en eksplicit henvisning til IntegerProducer, vi kan hente resultatet som en Heltal uden downcasting:

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

Et velkendt scenario er Objekt#klon metode, som returnerer en Objekt som standard. Når vi tilsidesætter klon () metode giver faciliteten af ​​covariante returtyper os mulighed for at have et mere konkret returobjekt end Objekt sig selv.

5. Konklusion

I denne artikel så vi, hvad kovarians- og covariantreturtypen er, og hvordan de opfører sig i Java.

Som altid er koden tilgængelig på GitHub.