Pergunta

Estou tendo dificuldade em tentar descobrir isso. Diga que tenho o seguinte código:

class Animal { }
class Mammal extends Animal { }
class Giraffe extends Mammal { }
...
public static List<? extends Mammal> getMammals() { return ...; }
...

public static void main(String[] args) {
    List<Mammal> mammals = getMammals(); // compilation error
}

Por que a atribuição resulta em um erro de compilação? O erro é algo como:

Type mismatch: cannot convert from List<capture#4-of ? extends Mammal> to List<Mammal>

De acordo com minha compreensão da covariância, o getMammals() O método retorna a list que sempre conterá Mammal Objetos para que sejam atribuíveis. o que estou perdendo?

Foi útil?

Solução

Porque getMammals poderia retornar um List<Giraffe>, e se isso fosse convertível para List<Mammal> Então você seria capaz de adicionar um Zebra para isso. Você não pode ter permissão para adicionar um Zebra para uma lista de Giraffe, você pode?

class Zebra extends Mammal { }

List<Giraffe> giraffes = new List<Giraffe>();

List<Mammal> mammals = giraffes; // not allowed

mammals.add(new Zebra()); // would add a Zebra to a list of Giraffes

Outras dicas

Bem, infelizmente não funciona assim.

Quando você declara getMammals () para retornar List<? extends Mammal> Isso significa que pode retornar List<Mammal> ou List<Giraffe> mas não List<Animal>

O seu main () deve ficar assim:

public static void main(String[] args) {
    List<? extends Mammal> mammals = getMammals();
    Mammal mammal = mammals.get(0);
}

EDIT: Em relação à covariância, é isso que geralmente se entende por isso:

class Animal {
    public Animal getAnimal() {return this;}
}

class Mammal extends Animal {
    public Mammal getAnimal() {return this;}
}

class Giraffe extends Mammal {
    public Giraffe getAnimal() {return this;}
}

Como você pode ver, ele permite sobrecarregar o tipo de retorno de métodos ao substituir o método.

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