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: