2012-09-15 21 views
12

Al anular un método de una superclase, Java permite que el tipo de retorno sea covariante.¿Por qué los tipos de parámetros contravariantes en Java no están permitidos para la anulación?

¿Por qué son contravariantes los tipos de parámetros en contraste no permitidos cuando se reemplazan los métodos?

+4

posible duplicado de [¿Por qué no hay contra-varianza de parámetro para anular?] (Http://stackoverflow.com/questions/2995926/why-is-there-no-parameter-contra-variance-for-overriding) –

+0

Gracias. He visto esto, pero tuve dificultades para entender la respuesta en C++, ya que estoy completamente familiarizado con C++. Pensé que sería más fácil preguntar específicamente por Java. – Will

+0

Leo la publicación vinculada y, por lo que entiendo, la ganancia de esta función no supera el factor de sorpresa aumentado. Y no es tan difícil proporcionar un método sobrecargado para una implementación específica. Me refiero a qué otros casos de uso para esta función ves? excepto por el método de llamada en la clase directamente? –

Respuesta

15

Porque se llama overloading.

En particular, el tipo de tipo de retorno puede ser covariante porque no se considera cuando se sobrecarga y, por lo tanto, sigue coincidiendo con la superclase o la implementación de la interfaz. Se tienen en cuenta los parámetros cuando se sobrecarga. Es muy posible que tenga una optimización con Number doSomethingWithNumber(Integer value) en comparación con Number doSomethingWithNumber(Number value).

+0

Suponiendo que tener parámetros contravariantes aún sería primordial, ¿cuáles son los problemas que nos encontramos? Estoy buscando algo así como: http://stackoverflow.com/a/2996901/715236, sin embargo, ¿qué sería malo tener en el método en una subclase anulando múltiples en una superclase? – Will

+0

El problema más grande sería la imposibilidad de proporcionar sobrecargas cuando se da una sobrecarga de tipo base en algún lugar de la cadena. Esto causaría estragos en las llamadas a funciones polimórficas, ya que la búsqueda tendría que cambiar de una firma igual simple a una firma igual o más básica, y ¿a qué debería llamar si tiene ambas, pero llame al más específico? Desde una perspectiva de diseño, si 'A extiende B', y' B extiende C', pero 'B' proporciona la implementación' void f (Object o) 'de su enlace, entonces' A' no tiene oportunidad de implementar más métodos específicos sobrecargados. Esto sería una pesadilla. – pickypg

+1

Lo que es más importante, creo, llevaría a API que se anulan perezosamente, lo que daría como resultado un código repetitivo increíblemente feo que internamente se usaría para llamar al método apropiado: 'void f (Object o) {if (o instancia de Entero) f ((Entero) o); } ' Y luego tienes que preguntarte ¿cómo funcionaría eso? Para permitir el comportamiento primordial, significaría que el método del parámetro 'Object' anula el método del parámetro' Integer', y por lo tanto el código anterior causaría un bucle infinito recursivo (hasta que la pila se desbordara) ya que caería directamente al ' Método Object' – pickypg

Cuestiones relacionadas