public class Pai {
Pai() {};
String m () {
return "metodo sobrescrito -- PAI";
}
String n (){
return "metodo nao sobrescrito -- classe pai";
}
}
public class Filho extends Pai {
Filho() {};
String m () {
return "metodo sobrescrito -- FILHO";
}
}
public class teste {
public static void main(String[] args) {
Pai pai = null;
Pai p = new Pai();
Filho filho = new Filho();
if (filho instanceof Pai) {
pai = filho;
p = (Pai)filho;
if (filho == pai)
System.out.println("true");
else
System.out.println("false");
//achei que fosse imprimir o método da clase pai
System.out.println(((Pai)pai).m());
//achei que não ia conseguir enxergar o método
System.out.println(pai.n());
//achei que fosse imprimir o método da clase pai
System.out.println(p.m());
}
}
}
o que imprime:
[quote]true
metodo sobrescrito – FILHO
metodo nao sobrescrito – classe pai
metodo sobrescrito – FILHO[/quote]
achei estranho o comportamento do programa, nas partes que eu comentei o código…
alguém poderia me explicar o porquê dessas coisas?
Sempre atente ao tipo real do objeto e não da referência.
Apesar de ser uma referência do tipo Pai, o objeto na realidade é do tipo Filho (pai = filho). Sendo assim, a versão que será chamada do método é de Filho e não de Pai.
Na segunda linha, como o método n não foi sobrescrito por filho, ele vai usar a versão herdada de pai (novamente por causa do pai = filho).
Na última, vc fez antes um cast de filho para pai (p = (Pai) filho;)… Esse cast é implícito, pois vc pode atribuir um objeto de uma subclasse a uma referência de superclasse. Os métodos vinculados serão da mesma forma.
Estude sobre polimorfismo e vinculação tardia para mais detalhes.
Em Java o comportamento padrão é diferente do comportamento padrão no C# e no C++.
Em C# e C++ você precisa usar a palavra-chave “virtual”, para que o método chamado dependa do tipo do objeto e não da variável. Se você não usar “virtual”, o método chamado depende do tipo da variável, não do objeto.
O padrão do Java é sempre usar o comportamento “virtual” para tudo que não é “static”. E é por isso que nem existe essa palavra-chave em Java, embora o Java tenha sido inspirado no C++.
Portanto, quem aprende Java sabendo já C# ou C++ acaba se complicando (um pouquinho) porque as coisas são um pouco diferentes.