OCJP - Questão de Herança

5 respostas
M

Bom dia pessoal, estou estudando para certificação e fiquei com uma dúvida (está em negrito)… Se puderem me ajudar. Segue o código:

public class Pai{
public String classe = “Pai”;

public String getClasse(){
	return this.classe;
}

public static void main(String args[]){
	Pai p = new Filho();
	System.out.println(p.classe); //[b]Dúvida... Imprime "Pai". Porque? Este não deveria ser herdado pela classe Filho?[/b]
	System.out.println(p.getClasse()); //Imprime "Filho"
}

}

class Filho extends Pai{
public String classe = “Filho”;

public String getClasse(){
	return this.classe;
}

}

Obrigado pela atenção.

5 Respostas

Rodrigo_Sasaki

Siga a seguinte “regrinha”:

Quando você acessar um atributo, ele irá buscar o atributo referente ao tipo da variável que no caso é Pai.

Quando invocar um método, ele irá invocar o método implementado no objeto real não no tipo da variável, então nesse caso invoca o método de Filho

drsmachado

Não.
Você está criando um objeto da classe Pai e não da classe Filho.
Como assim?
Quando você tem a declaração

Pai p = new Filho();

Você está criando o objeto p a partir da classe Filho, mas, definindo como um objeto que da classe Pai. Em outras palavras, seria como se você fizesse um exame de DNA e obtivesse as características do pai, a partir de uma amostra do filho.
Isso fica mais claro quando utilizamos interfaces. É sabido que uma interface precisa ser implementada, logo, se você tentar fazer isso

List<Churrasco> churras = new List<Churrasco>();

Terá um erro, pois, todos os métodos da interface List precisam ser implementados.
Como também é sabido, temos as implementações ArrayList e LinkedList e, além destas, podemos criar as nossas próprias implementações, de acordo com nossa necessidade. Isso nos permite fazer coisas assim

public interface Churrasqueiro{
   public void colocarMaisCarne(Carne carne);
}
//E a implementação
public class ChurrasqueiroImpl implements Churrasqueiro{
   public Carne retirarCarne(){
     if(pedaço.isNoPonto(){
       return pedaco;
    }
   }
   
   public void colocarMaisCarne(Carne carne){
     if(isBrasaAtiva(){
       carne.setEmProcesso(true);
    }
   }
}

Se declararmos

Churrasqueiro chu = new ChurrasqueiroImpl();

O método retirarCarne não será visível no objeto chu, visto que, a interface Churrasqueiro não o possui.

M

Show… Rodrigo, posso concluir que a herança só funciona para encapsulamento? Ou estou errado? Pelo menos pra mim faz sentido nesta situação.

Rodrigo_Sasaki

Na verdade o problema nesse caso é que uma variável está sombreando a outra.

Sombreamento acontece quando você tem 2 variáveis com o mesmo nome no mesmo lugar, só que as duas tem escopo diferente. O exemplo clássico é um setter:public void String setNome(String nome){ this.nome = nome; }Nesse exemplo você tem 2 variáveis nome, a que recebe como argumento, e o membro da classe. Para diferenciar qual é qual você usa o this.

Se você não indicar qual quer, e simplesmente usar nome o compilador vai entender que você está se referenciando à variável com escopo menor.

Para ver que você tem acesso às duas variáveis, altere seu método getClasse na classe Filho, deixe assim:public String getClasse(){ return this.classe + " - " + super.classe; }

sergiotaborda

Não. Você pode concluir que o polimorfismo dinâmico só se aplica a métodos.

metodos =/= encapsulamento
polimorfismo =/= herança

Criado 20 de dezembro de 2012
Ultima resposta 20 de dez. de 2012
Respostas 5
Participantes 4