Covariant - Duvida

Estava fazendo o simulado do Wihizlabs e achei a seguinte questão:

[code]
class A{
int x = 5;
}

class B extends A{
int x = 6;
}

public class Covariant {
public A getObject(){ //Linha 3
return new A();
}
public static void main(String a[]){
Covariant c1 = new SubCovariantTest();
System.out.println(c1.getObject().x); // Linha 1
}
}

class SubCovariantTest extends Covariant{
public B getObject(){ // Linha 2
return new B();
}
}[/code]

O resultado deste codigo é: 5

A minha duvida é: Porque a Linha 1 chama o metodo da linha 3 ao inves do metodo da linha 2, sendo que c1 tem referencia para o metodo contido na classe SubCovariantTest.

Pois tem um erro no código, na linha 2 você colocou :

public B getObjectc(){ // Linha 2

ao invés de :

public A getObject(){ // Linha 2

a assinatura esta diferente, portanto não tem sobre-escrita do método. Tente esta mudança e verá que terá como resposta 6.

Desculpe-me, mandei a segunda linha errada, tem que ser :

 	public B getObject(){ // Linha 2

se colocar

 	public A getObject(){ // Linha 2

continua recebendo 5 como resposta.

Acho que estou fazendo confusão mas,

e

Existe sobrescrita de metodo, porque B extende A, logo B é uma covariante de A, então não altera a assinatura do metodo.

O que eu quero saber é porque a JVM chama o metodo da linha 3 sendo que c1 tem referencia para a classe SubCovariantTest, então deveria chamar o metodo na linah 2.

Nossa, acho que estou bobeando em algum ponto, essa esta dificil de entender… :x

Na verdade não chama o método da linha 3 não, é um problema de interpretação do encapsulamento. Se vc pegar e exibir qual objeto foi instanciado :

  System.out.println(c1.getObject().getClass().getName());

Em ambas assinaturas, vc vai notar que ele está iniciando certo o objeto a partir de B. Porém vc está acessando um atributo, e neste caso ele utiliza o nome da classe para fazer a decisão e não a tabela virtual de sobre-escrita.

Tente o seguinte código:

class A{ private int x = 5; public int getX() { return x; } } class B extends A{ private int x = 6; public int getX() { return x; } }

e ao invés de chamar c1.getObject().x chame c1.getObject().getX() vai notar que tudo roda como seria esperado.

seduardo, muito obrigado,

Agora consegui entender… :lol: