O que é um tipo de retorno covariante?
-
18-09-2019 - |
Pergunta
O que é um tipo de retorno covariante em Java? Na programação orientada a objetos em geral?
Solução
Retorno covariante significa que, quando substitui um método, o tipo de retorno do método de substituição pode ser um subtipo do tipo de retorno do método substituído.
Para esclarecer isso com um exemplo, um caso comum é Object.clone()
- que é declarado devolver um tipo de Object
. Você pode substituir isso em sua própria classe da seguinte maneira:
public class MyFoo
{
...
// Note covariant return here, method does not just return Object
public MyFoo clone()
{
// Implementation
}
}
O benefício aqui é que qualquer método que possua uma referência explícita a um objeto MyFoo poderá invocar clone()
e saiba (sem lançar) que o valor de retorno é uma instância de MyFoo
. Sem os tipos de retorno covariante, o método substituído em Myfoo teria que ser declarado retornar Object
- e, portanto, o código de chamada teria que diminuir explicitamente o resultado da chamada do método (mesmo que os dois lados "saibam" que só pode ser uma instância do MyFoo).
Observe que não há nada de especial em clone()
e que qualquer método substituído pode ter um retorno covariante - eu o usei como exemplo aqui, pois é um método padrão em que isso geralmente é útil.
Outras dicas
Aqui está outro exemplo simples:
Animal
classe
public class Animal {
protected Food seekFood() {
return new Food();
}
}
Dog
classe
public class Dog extends Animal {
@Override
protected Food seekFood() {
return new DogFood();
}
}
É possível modificar o tipo de retorno do Dog
's seekFood()
método para DogFood
- uma subclasse de Food
, como mostrado abaixo:
@Override
protected DogFood seekFood() {
return new DogFood();
}
Isso é perfeitamente uma substituição legal e o tipo de retorno de Dog
's seekFood()
O método é conhecido como Tipo de retorno covariante.
A partir do lançamento do JDK 1.5, os tipos covariantes foram introduzidos em Java. E vou explicar isso com um caso simples:: Quando substituímos uma função, a função pode fazer alterações no comportamento do seu É isso que você lê na maioria dos livros, mas o que eles {autores} perdem é que também podemos alterar o tipo de retorno. Verifique o link abaixo para obter esclarecimentos, podemos alterar o tipo de retorno, desde que possa ser atribuído para retornar o tipo de versão base do método.
Portanto, esse recurso dos tipos derivados de retorno é chamado de covariante ...
Os tipos de devolução covariante significa simplesmente retornar a própria referência de classe ou sua referência de classe infantil.
class Parent {
//it contain data member and data method
}
class Child extends Parent {
//it contain data member and data method
//covariant return
public Parent methodName() {
return new Parent();
or
return Child();
}
}
O tipo de retorno covariante especifica que o tipo de retorno pode variar na mesma direção que a subclasse
class One{
One get(){return this;}
}
class Two extends One{
Two get(){return this;}
void message(){
System.out.println("After Java5 welcome to covariant return type");
}
public static void main(String args[]){
new Two().get().message();
}
}
Antes do Java 5, não foi possível substituir nenhum método alterando o tipo de retorno. Mas agora, desde Java5,
É possível substituir o método alterando o tipo de retorno se a subclasse substituir qualquer método cujo tipo de retorno não for primitivo, mas altera seu tipo de retorno para o tipo de subclasse.
- Ajuda a evitar o tipo confuso de elencos presentes na hierarquia de classes e, assim, tornando o código legível, utilizável e sustentável.
Temos a liberdade de ter tipos de retorno mais específicos ao substituir
métodos.Ajuda para prevenir o ClassCastException de tempo de execução em devoluções
Referência: www.geeksforgeeks.org
- O tipo de retorno covariante em Java permite restringir o tipo de retorno do método substituído.
- Esse recurso ajudará a evitar o lançamento do lado do cliente. Ele permite que o programador seja programado sem a necessidade de verificação de tipo e fundição.
- O tipo de retorno covariante sempre funciona apenas para tipos de retorno não primitivos.
interface Interviewer {
default Object submitInterviewStatus() {
System.out.println("Interviewer:Accept");
return "Interviewer:Accept";
}
}
class Manager implements Interviewer {
@Override
public String submitInterviewStatus() {
System.out.println("Manager:Accept");
return "Manager:Accept";
}
}
class Project {
public static void main(String args[]) {
Interviewer interviewer = new Manager();
interviewer.submitInterviewStatus();
Manager mgr = new Manager();
mgr.submitInterviewStatus();
}
}
Outro exemplo é de Java,
Unaryoperator.java
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
/**
* Returns a unary operator that always returns its input argument.
*
* @param <T> the type of the input and output of the operator
* @return a unary operator that always returns its input argument
*/
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
Function.java
@FunctionalInterface
public interface Function<T, R> {
........
........
........
........
static <T> Function<T, T> identity() {
return t -> t;
}
}
Antes do Java5, não foi possível substituir nenhum método alterando o tipo de retorno. Mas agora, desde o Java5, é possível substituir o método alterando o tipo de retorno se a subclasse substituir qualquer método cujo tipo de retorno não seja primitivo, mas altera seu tipo de retorno para o tipo de subclasse.