O que é um tipo de retorno covariante em Java? Em programação orientada a objetos em geral?
O que é um tipo de retorno covariante em Java? Em programação orientada a objetos em geral?
Respostas:
Retorno covariante, significa que quando alguém sobrescreve um método, o tipo de retorno do método sobrescrita pode ser um subtipo do tipo de retorno do método sobrescrito.
Para esclarecer isso com um exemplo, um caso comum é Object.clone()
- que é declarado para retornar 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 contenha uma referência explícita a um objeto MyFoo será capaz de invocar clone()
e saber (sem lançar) que o valor de retorno é uma instância de MyFoo
. Sem os tipos de retorno covariante, o método sobrescrito em MyFoo teria que ser declarado para retornar Object
- e então o código de chamada teria que reduzir explicitamente o resultado da chamada do método (mesmo que ambos os lados "saibam" que só pode ser uma instância de MyFoo )
Observe que não há nada de especial clone()
e que qualquer método substituído pode ter um retorno covariante - usei-o como um exemplo aqui, pois é um método padrão onde geralmente é útil.
List<Foo>
e List<FooBar>
?
clone()
como sendo um Method<Void, Object>
e perguntar se o mais específico pode Method<Void, MyFoo>
ser atribuído a esse tipo de pai. O que é, se e somente se os métodos Java são covariantes em seu tipo de retorno.
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 um primordial legal, e o tipo de retorno Dog
do seekFood()
método é conhecido como tipo de retorno covariant .
A partir do lançamento do JDK 1.5, os tipos covariant foram introduzidos em Java. e vou explicar para você com um caso simples: Quando substituímos uma função, a função tem permissão para fazer alterações em seu comportamento isso é o que você lê na maioria dos livros, mas o que eles {autores} perdem é que podemos alterar o tipo de retorno também. verifique o link abaixo para esclarecimento, podemos alterar o tipo de retorno, desde que possa ser atribuído ao tipo de retorno da versão Base do método.
Portanto, esse recurso de retornar tipos derivados é chamado de COVARIANTE ...
Os tipos de retorno covariant simplesmente significam retornar a própria referência de classe ou sua referência de classe filha.
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();
}
}
Parent.foo()
retorna um tipo não relacionadoA
e Child.foo()
retorna um tipo B
derivado de A
.
Para adicionar às respostas acima, a substituição é possível entre os tipos de retorno co-variantes, com a restrição de que o tipo de retorno do método de substituição (método da subclasse) deve ser uma subclasse do tipo de retorno do método substituído (método da superclasse). Isso é válido do Java 5 em diante.
O tipo de retorno covariante especifica que o tipo de retorno pode variar na mesma direção da 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 era possível substituir nenhum método alterando o tipo de retorno. Mas agora, desde Java5,
é possível sobrescrever o método alterando o tipo de retorno se a subclasse sobrescrever qualquer método cujo tipo de retorno seja Não-Primitivo, mas ele altera seu tipo de retorno para o tipo de subclasse.
Temos a liberdade de ter tipos de retorno mais específicos ao substituir
métodos.
Ajuda na prevenção de ClassCastExceptions em tempo de execução em devoluções
referência: www.geeksforgeeks.org
- O tipo de retorno covariant em java permite estreitar o tipo de retorno do método substituído.
- Esse recurso ajudará a evitar downcast no lado do cliente. Ele permite que o programador programe sem a necessidade de verificação de tipo e conversão para baixo.
- 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 era possível substituir nenhum método alterando o tipo de retorno. Mas agora, desde o Java5, é possível sobrescrever o método alterando o tipo de retorno se a subclasse sobrescrever qualquer método cujo tipo de retorno seja Não-Primitivo, mas altere seu tipo de retorno para o tipo de subclasse.