El mecanismo de covariant return types permite en Java, al sobrescribir un método (overriding), devolver un tipo que no es exactamente el mismo que en la superclase, sino su subtipo (tipo covariante).
Esto aumenta la expresividad del código, permitiendo obtener tipos más específicos sin una conversión explícita.
Ejemplo:
class Animal { } class Dog extends Animal { } class Parent { Animal getAnimal() { return new Animal(); } } class Child extends Parent { @Override Dog getAnimal() { return new Dog(); } // Retorno covariante }
Condiciones para su funcionamiento:
¿Se puede en una subclase cambiar el tipo de retorno de un método sobrecargado (overloaded method) para que sea un subtipo del base? ¿Se consideraría una sobrecarga válida?
Respuesta: No, para la sobrecarga (overloading) solo importa la firma de los parámetros, y el tipo de retorno no tiene relevancia. No se puede cambiar solo el tipo de retorno en una sobrecarga; tal método entraría en conflicto por la firma.
Ejemplo:
class Example { Animal make() { return new Animal(); } // Dog make() { return new Dog(); } // Error de compilación: método duplicado! }
La covarianza funciona solo para overriding (sobrescritura).
Historia
En el proyecto, el programador cometió un error y añadió un método sobrecargado con el mismo nombre y parámetros, pero con un tipo de retorno diferente, esperando que esto fuera una "sobrescritura covariante". Como resultado, el proyecto no compiló, y el error solo se detectó durante el CI.
Historia
Al utilizar el retorno covariante en la jerarquía de clases, el desarrollador aplicó incorrectamente los tipos parametrizados (generics), sin implementar correctamente los subtipos, lo que provocó un error ClassCastException en tiempo de ejecución al trabajar con colecciones.
Historia
En el método sobrescrito se devolvía un tipo más especializado, pero el equipo no documentó este contrato. En el código que funcionaba a través del tipo base, surgieron dificultades con las conversiones de tipo y un comportamiento inesperado durante el "upcast" de referencias, lo que condujo a una serie de errores ocultos.