Pergunta

O que é um tipo de retorno covariante em Java? Na programação orientada a objetos em geral?

Foi útil?

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 métodos substituídos podem diferem no tipo de retorno?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top