Het Covariante Return Type in Java

1. Overzicht

In deze zelfstudie gaan we het covariante retourtype in Java nader bekijken. Voordat we covariantie onderzoeken vanuit het oogpunt van het retourtype, laten we eens kijken wat dat betekent.

2. Covariantie

Covariantie kan worden beschouwd als een contract voor hoe een subtype wordt geaccepteerd wanneer alleen het supertype is gedefinieerd.

Laten we eens kijken naar een paar basisvoorbeelden van covariantie:

Lijst integerList = nieuwe ArrayList (); Lijst doubleList = nieuwe ArrayList ();

Zocovariantie betekent dat we toegang hebben tot specifieke elementen die zijn gedefinieerd via hun supertype. Echter, we mogen geen elementen in een covariant systeem plaatsen, aangezien de compiler het feitelijke type van de generieke structuur niet zou kunnen bepalen.

3. Het covariante retourtype

De covariant retourtype is - wanneer we een methode overschrijven - waardoor het retourtype het subtype kan zijn van het type van de overschreven methode.

Laten we, om dit in de praktijk te brengen, een eenvoudig nemen Producent klas met een produceren() methode. Standaard retourneert het een Draad als een Voorwerp om flexibiliteit te bieden aan de kinderklassen:

public class Producer {public Object produceren (String input) {Object resultaat = input.toLowerCase (); resultaat teruggeven; }}

Als gevolg van de Voorwerp als een retourtype kunnen we een meer concreet retourtype hebben in de kindklasse. Dat is het covariante retourtype en levert getallen op uit tekenreeksen:

public class IntegerProducer breidt Producer uit {@Override public Integer produce (String input) {return Integer.parseInt (input); }}

4. Het gebruik van de structuur

Het belangrijkste idee achter de covariante retourtypen is om de Liskov-substitutie te ondersteunen.

Laten we bijvoorbeeld eens kijken naar het volgende producentenscenario:

@Test openbare leegte whenInputIsArbitrate_thenProducerProducesString () {String arbitraireInput = "gewoon een willekeurige tekst"; Producer producer = nieuwe Producer (); Object objectOutput = producer.produce (arbitraire invoer); assertEquals (arbitraireInput, objectOutput); assertEquals (String.class, objectOutput.getClass ()); }

Na het veranderen naar IntegerProducerkan de bedrijfslogica die het resultaat daadwerkelijk oplevert dezelfde blijven:

@Test openbare leegte whenInputIsSupported_thenProducerCreatesInteger () {String integerAsString = "42"; Producer producer = nieuwe IntegerProducer (); Object resultaat = producer.produce (integerAsString); assertEquals (Integer.class, result.getClass ()); assertEquals (Integer.parseInt (integerAsString), resultaat); }

We verwijzen echter nog steeds naar het resultaat via een Voorwerp. Elke keer dat we een expliciete verwijzing naar de Geheel getal Producent, we kunnen het resultaat ophalen als een Geheel getal zonder downcasting:

@Test openbare leegte whenInputIsSupported_thenIntegerProducerCreatesIntegerWithoutCasting () {String integerAsString = "42"; IntegerProducer producer = nieuwe IntegerProducer (); Integer resultaat = producer.produce (integerAsString); assertEquals (Integer.parseInt (integerAsString), resultaat); }

Een bekend scenario is het Voorwerp#kloon methode, die een Voorwerp standaard. Elke keer dat we het kloon () methode, stelt de faciliteit van covariante retourtypen ons in staat om een ​​concreter retourobject te hebben dan de Voorwerp zelf.

5. Conclusie

In dit artikel hebben we gezien wat de covariantie- en covariante retourtypen zijn en hoe ze zich gedragen in Java.

Zoals altijd is de code beschikbaar op GitHub.