Het mechanisme van covariant return types staat in Java toe om bij het overschrijven van een methode (overriding) niet exact hetzelfde type als in de superklasse te retourneren, maar een subtype (covariant type).
Dit verhoogt de expressiviteit van de code, waardoor meer specifieke types kunnen worden verkregen zonder expliciete casting.
Voorbeeld:
class Animal { } class Dog extends Animal { } class Parent { Animal getAnimal() { return new Animal(); } } class Child extends Parent { @Override Dog getAnimal() { return new Dog(); } // Covariante retour }
Voorwaarden voor werking:
Is het mogelijk om in een subklasse het geretourneerde type van een overbelaste methode (overloaded method) te veranderen zodat het een subtype van het basis type is? Zou dit als een geldige overbelasting worden beschouwd?
Antwoord: Nee, voor overbelasting (overloading) is alleen de handtekening van de parameters belangrijk, en het geretourneerde type speelt geen rol. Alleen het geretourneerde type veranderen in overbelasting is niet toegestaan - zo'n methode zou conflicteren in handtekening.
Voorbeeld:
class Example { Animal make() { return new Animal(); } // Dog make() { return new Dog(); } // Compilefout: dubbele methode! }
Covariantie werkt alleen voor overriding.
Geschiedenis
In een project maakte de programmeur een fout door een overbelaste methode met dezelfde naam en parameters toe te voegen, maar met een ander geretourneerd type, in de veronderstelling dat dit een "covariant overname" was. Als gevolg hiervan compileerde het project niet, en de bug werd pas tijdens CI ontdekt.
Geschiedenis
Bij het gebruik van covariant return in een hiërarchie van klassen, paste de ontwikkelaar parameterized types (generics) onjuist toe door de subtypen niet goed te implementeren, waardoor een ClassCastException-fout tijdens runtime optrad bij het werken met collecties.
Geschiedenis
In de overschreven methode werd een meer gespecialiseerd type geretourneerd, maar het team documenteerde deze overeenkomst niet. In de code die door het basis type werkte, waren er problemen met typecasting en onverwacht gedrag bij "upcast" verwijzingen, wat leidde tot verschillende verborgen fouten.