Dúvida herança

11 respostas
matheusjava

Pessoal, tava fazendo um mock do Enthuware e essa questão apareceu:

public class Baap {
    public int h = 4;
    public int getH() {
        System.out.println("Baap " + h);
        return h;
    }
    
}

class Beta extends Baap {
    public int h = 44;
    public int getH() {
        System.out.println("Beta " + h);
        return h;
    }
    
    public static void main(String[] args) {
        Baap b = new Beta();
        System.out.println(b.h + " " + b.getH());
    }
}

Ele diz q a saída é: Beta 44 4 44. Não entendo porque o método roda primeiro.

Alguém poderia me explicar?

Obrigado

11 Respostas

E

Uma forma de você nunca se perder com esse problema é lembrar que a parte de sobreposição (override) de membros públicos (não-static) é igual à de métodos estáticos públicos. Para facilitar, pense que o programa é equivalente ao seguinte:

public class Baap {  
        public static int get_H() { return 4; }
        public int getH() {  
            System.out.println("Baap " + get_H());  
            return get_H();  
        }  
          
    }  
      
    class Beta extends Baap {  
        public static int get_H() { return 44; }
        public int getH() {  
            System.out.println("Beta " + get_H());  
            return get_H();  
        }  
          
        public static void main(String[] args) {  
            Baap b = new Beta();  
            System.out.println(b.get_H() + " " + b.getH());  
        }  
    }
matheusjava

Obrigado pela rápida resposta. Mas a minha dúvida é por que o último elemento é processado primeiro?

Fexx

Não sei se entendi sua duvida. mas vamos lá.

Por causa disso:

Baap b = new Beta();

Ou seja vc está criando um objeto do tipo Beta e armazenando em b, ou seja ele vai pegar do mais especifico.

se fosse assim:

Baap b = new Baap();

o resultado seria:
Baap 4 4 4.

whitespace

Bom, nesse codigo acontece o seguinte:
em

todos valores são obtidos antes que println seja executado, sendo assim

b.getH() é executado: imprimindo “Beta 44” e retornando 44

depois há uma concatenação de b.h com valor retornado de b.getH formando a saida “4 44”.

Juntando as saidas da o resultado correto.

Lembre que não existe override em variáveis de instância.

matheusjava

Eu entendo q nao existe sobrescrita em variaveis de instancia, so nao entendo pq o final do System.out.println() é executado primeiro =/

whitespace

O que acontece é que vc passa uma String para println() e essa String deve estar completa. Fique atento com esse tipo de questão.

G

depurando percebe-se facilmente isso

sidney.tavares

matheusjava:
Pessoal, tava fazendo um mock do Enthuware e essa questão apareceu:

public class Baap {
    public int h = 4;
    public int getH() {
        System.out.println("Baap " + h);
        return h;
    }
    
}

class Beta extends Baap {
    public int h = 44;
    public int getH() {
        System.out.println("Beta " + h);
        return h;
    }
    
    public static void main(String[] args) {
        Baap b = new Beta();
        System.out.println(b.h + " " + b.getH());
    }
}

Ele diz q a saída é: Beta 44 4 44. Não entendo porque o método roda primeiro.

Alguém poderia me explicar?

Obrigado

Se ainda estiver com dúvida eu acredito que a resposta para sua pergunta está no polimorfismo, veja que aqui:

Baap b = new Beta();

Há uma atribuição polimórfica correto? Um Beta é um Baap. Neste caso a chamada ao método é feita em tempo de execução e não de compilação, quando a linha:

System.out.println(b.h + " " + b.getH());

o método getH() chamado é o da subclasse em tempo de execução(Beta 44), quando ele chama b.h ele está chamando os valores contidos na variável em ambas as classes não nenhum método. O último elemento é processado primeiro porque trata-se de um método.

faeldix

olhem isso:

package heranca;

public class TesteQualquer {

	public int value = 5;
	
	public String metodo(){
		return "TesteQualquer";
	}

}

e

package heranca;

public class TesteQualquer2 extends TesteQualquer {

	public int value = 10;
	
	public String metodo(){
		return "TesteQualquer2";
	}

}

e

package heranca;

public class MainMethod {

	public static void main(String[] args) {
	
		TesteQualquer2 cm = new TesteQualquer2();
		System.out.println(cm.value);
		System.out.println(cm.metodo());
		
		
		TesteQualquer cmd = cm;
		System.out.println(cmd.value);
		System.out.println(cmd.metodo());
	
	}

}

a saida foi

C:\java\classes>java heranca.MainMethod 10 TesteQualquer2 5 TesteQualquer2

C:\java\classes>

mas eu realmente estava esperando que saisse:

C:\java\classes>java heranca.MainMethod 10 TesteQualquer2 5 TesteQualquer

C:\java\classes>

sidney.tavares

Olá FaelDix

Cara, esse código tem a mesma explicação, nessa linha

TesteQualquer2 cm = new TesteQualquer2();

Acho que não tem segredo, é uma invocação simples e no caso serão chamados o método da classe e o atributo também, por isso a primeira saída é

10 TesteQualquer2
Já nessa linha

é como se você estivesse fazendo

ocorre polimorfismo, porque a variável cm, do tipo TesteQualquer2, passa no teste é-um para o tipo TesteQualquer, lembre-se que na sobrescrição o que vale é o tempo de execução e não de compilação, no caso das variáveis, as mesmas não estão sendo herdadas e quando o código compila elas já recebem seus valores, por isso a saída:

5 TesteQualquer2

faeldix

cara pior que vou te confessar.. ja to desde a tarde inteira.. tentando entender isso.. e nada.. pq quando eu uso um metodo funciona.. e quando eu acesso diretamente nao?

package heranca;

public class MinhaClasse {
	
	int value = 5;

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}
	
	

}
package heranca;

public class ClasseFilha extends MinhaClasse {

	int value = 6;
	
}
package heranca;

public class MainMethod {

	public static void main(String[] args){
		MinhaClasse x = new ClasseFilha();
		System.out.println(x.value);
		System.out.println(x.getValue());
		
		ClasseFilha z = (ClasseFilha) x;
		System.out.println(z.value);
		System.out.println(z.getValue());
	}
	
}

saida:

5
5
6
5

pq quando eu acesso diretamente da o valor certo.. e quando eu uso o metodo nao? :S

EDIT: ja achei a resposta.. como nao existe o metodo na classe filha.. o metodo usa o metodo da classe pai e pega o valor da classe pai TBM.

Criado 21 de março de 2012
Ultima resposta 7 de mai. de 2012
Respostas 11
Participantes 7