¿Pueden los métodos anulados tener diferentes tipos de retorno ?
java
methods
overriding
santidoo
fuente
fuente
error: method() in subclass cannot override method() in superclass
Respuestas:
Java admite * tipos de retorno covariantes para métodos anulados. Esto significa que un método anulado puede tener más tipo de retorno específico. Es decir, siempre que el nuevo tipo de retorno sea asignable al tipo de retorno del método que está anulando, está permitido.
Por ejemplo:
Esto se especifica en la sección 8.4.5 de la Especificación del lenguaje Java :
("| R2 |" se refiere a la eliminación de R2, como se define en §4.6 del JLS ).
* Antes de Java 5, Java tenía tipos de retorno invariables , lo que significaba que el tipo de retorno de una anulación de método necesitaba coincidir exactamente con el método que se anulaba.
fuente
Sí, puede diferir, pero hay algunas limitaciones.
Antes de Java 5.0, cuando anula un método, ambos parámetros y el tipo de retorno deben coincidir exactamente. En Java 5.0, introduce una nueva instalación llamada tipo de retorno covariante. Puede anular un método con la misma firma pero devuelve una subclase del objeto devuelto. En otras palabras, un método en una subclase puede devolver un objeto cuyo tipo es una subclase del tipo devuelto por el método con la misma firma en la superclase.
fuente
Sí, si devuelven un subtipo. Aquí hay un ejemplo:
Este código se compila y se ejecuta.
fuente
En términos generales, sí, el tipo de retorno del método de anulación puede ser diferente. Pero no es sencillo, ya que hay algunos casos involucrados en esto.
Caso 1: si el tipo de retorno es un tipo de datos primitivo o nulo.
Salida: si el tipo de retorno es nulo o primitivo, el tipo de datos del método de clase principal y el método de anulación deberían ser los mismos. por ejemplo, si el tipo de retorno es int, float, string, entonces debería ser el mismo
Caso 2: si el tipo de retorno es un tipo de datos derivado:
Salida: si el tipo de retorno del método de la clase principal es el tipo derivado, entonces el tipo de retorno del método de anulación es el mismo tipo de datos derivados de la subclase al tipo de datos derivados. por ejemplo, supongamos que tengo una clase A, B es una subclase de A, C es una subclase de B y D es una subclase de C; entonces, si la superclase devuelve el tipo A, entonces el método de anulación es la subclase puede devolver el tipo A, B, C o D, es decir, sus subtipos. Esto también se llama covarianza.
fuente
sí Es posible ... el tipo de retorno puede ser diferente solo si el tipo de retorno del método de la clase primaria es
un supertipo del tipo de retorno del método de la clase secundaria ...
significa
Si este es el tipo de retorno diferente, se puede permitir ...
fuente
Bueno, la respuesta es si o no.
Depende de la pregunta. todos aquí respondieron con respecto a Java> = 5, y algunos mencionaron que Java <5 no presenta tipos de retorno covariantes.
en realidad, la especificación del lenguaje Java> = 5 lo admite, pero el tiempo de ejecución de Java no. en particular, la JVM no se actualizó para admitir tipos de retorno covariantes.
En lo que se vio entonces como un movimiento "inteligente", pero terminó siendo una de las peores decisiones de diseño en la historia de Java, Java 5 implementó un montón de nuevas características de lenguaje sin modificar la JVM o la especificación del archivo de clase. en su lugar, todas las características se implementaron con trucos en javac: el compilador genera / usa clases simples para clases anidadas / internas, borrado de tipos y moldes para genéricos, accesores sintéticos para "amistad" privada anidada / interna, campos de instancia sintéticos para "esto" externo punteros, campos estáticos sintéticos para literales '.class', etc., etc.
y los tipos de retorno covariante son aún más azúcar sintáctico agregado por javac.
por ejemplo, al compilar esto:
javac generará dos métodos get en la clase Derivada:
El método puente generado (marcado
synthetic
ybridge
en código de bytes) es lo que realmente se anulaObject:Base:get()
porque, para la JVM, los métodos con diferentes tipos de retorno son completamente independientes y no pueden anularse entre sí. Para proporcionar el comportamiento esperado, el puente simplemente llama a su método "real". en el ejemplo anterior, javac anotará métodos puente y reales en Derivado con @SomeAnnotation.tenga en cuenta que no puede codificar manualmente esta solución en Java <5, porque los métodos bridge y real solo difieren en el tipo de retorno y, por lo tanto, no pueden coexistir en un programa Java. pero en el mundo de JVM, los tipos de retorno de métodos son parte de la firma del método (al igual que sus argumentos) y, por lo tanto, los dos métodos nombrados igual y tomando los mismos argumentos son considerados completamente independientes por la JVM debido a sus diferentes tipos de retorno, y puede coexistir
(Por cierto, los tipos de campos son igualmente parte de la firma del campo en bytecode, por lo que es legal tener varios campos de diferentes tipos pero con el mismo nombre dentro de una sola clase de bytecode).
para responder completamente a su pregunta: la JVM no admite tipos de retorno covariantes, pero javac> = 5 lo simula en tiempo de compilación con una capa de azúcar sintáctico dulce.
fuente
Anulación y tipos de retorno, y retornos covariantes
La subclase debe definir un método que coincida exactamente con la versión heredada. O, a partir de Java 5, puede cambiar el tipo de retorno en
Código de muestra
Java 5, este código se compilará. Si intentara compilar este código con un compilador 1.4 dirá que intenta usar un tipo de retorno incompatible - sandeep1987 hace 1 minuto
fuente
Las otras respuestas son todas correctas, pero sorprendentemente todas omiten el aspecto teórico aquí: los tipos de retorno pueden ser diferentes, pero solo pueden restringir el tipo utilizado en la superclase debido al Principio de sustitución de Liskov .
Es súper simple: cuando tienes un código de "cliente" que llama a algún método:
entonces lo anterior tiene que funcionar (y devolver algo que es un
int
no importa qué implementaciónbar()
se invoque).Significado: si hay una subclase de Bar que anula,
bar()
entonces todavía tiene que devolver algo que no rompa el "código de llamada".En otras palabras: suponga que se supone que la base
bar()
debe devolver int. Entonces, una subclase podría regresarshort
, pero nolong
porque las personas que llamen estarán bien tratando con unshort
valor, ¡pero no con unlong
!fuente
El tipo de retorno debe ser el mismo o un subtipo del tipo de retorno declarado en el método anulado original en la superclase.
fuente
SÍ, puede ser posible
fuente
Si. Es posible que los métodos anulados tengan un tipo de retorno diferente.
Pero las limitaciones son que el método reemplazado debe tener un tipo de retorno que sea un tipo más específico del tipo de retorno del método real.
Todas las respuestas han dado ejemplos del método reemplazado para tener un tipo de retorno que es una subclase del tipo de retorno del método real.
Por ejemplo :
Pero esto no solo se limita a la subclase. Incluso las clases que implementan una interfaz son un tipo específico de la interfaz y, por lo tanto, pueden ser un tipo de retorno donde se espera que la interfaz.
Por ejemplo :
fuente
fuente