to tentando achar uma razão para esse código funcionar, dêem uma olhada:
package pacote;
public class Animal {
protected void metodo(){
System.out.println("metodo animal");
}
}
package outroPacote;
import pacote.Animal;
public class Cavalo extends Animal{
protected void metodo(){
System.out.println("metodo Cavalo");
}
}
package pacote;
import outroPacote.Cavalo;
public class Teste
{
public static void main(String[] args){
Animal a = new Cavalo();
a.metodo();
}
}
A saída de dados é: metodo Cavalo.
Dúvida: O método sobrescrito em cavalo, possúi o modificador de Acesso “protected”, ou sejá só deveria ser acessado em subclasses de Cavalo ou no mesmo pacote.
No exemplo acima, a classe Teste não é subclasse de cavalo e nem está no mesmo pacote, porém em tempo de execução, o metodo protected é acessado normalmente.
devo lembrar que o código está compilando e rodando normalmente, a minha dúvida é como o método sobrescrito consegue ser executado com o modificador protected.
OBS: Cavalo c = new Animal(); Não funcionaria, acho que você se confundiu.
Uma referência de Animal pode receber uma instância de Cavalo perfeitamente, pois Cavalo é um Animal (uma vez que: Cavalo extends Animal). Porém uma referência de Cavalo não pode receber uma instancia de Animal, pois Animal pode não ser um Cavalo. Concorda?
O modificador protected é menos “rígido” do que modificador default.
Utilizando default (ou seja, deixando de colocar qualquer modificador) num método, as sub classes somente herdam esse método se estiverem no mesmo pacote. O que não acontece com protected. Mesmo classes de outros pacotes herdam os métodos protected.
Resumindo:
default: restrição a nível de pacote para herança e simples acesso
protected: restrição a nível de pacote para simples acesso
Primeiramente parabens por estar estudando para a certificacao, o que o JavaMania disse realmente esta errado, isso aqui nao existe :
Cavalo c = new Animal();
pois nao vai funcionar, o certo eh o contrario como voce disse, mas vou explicar o que acontece no seu codigo.
A classe Teste nao precisa fazer parte de heranca nenhuma, voce usa ela exatamente como o nome diz “Teste” ,
Entao dentro do main quando voce faz isso :
Animal a = new Cavalo();
a.metodo();
voce esta instanciando, imagina assim eh como se voce pegasse o codigo dessas classes Animal e Cavalo e colocasse tudo dentro do metodo main, entende, entao todo o codigo tanto de Animal quanto de Cavalo passa a estar dentro desse metodo main(ou seja, roda dentro do main) e classe teste serve apenas digamos de “carcaça” (essa foi boa rsrsrs) para o codigo funcionar.
bem ta numa linguagem assim bem leiga, mas faco isso para que voce tente entender o conceito.
espero que eu tenha ajudado ,
se nao posta ai que eu tento explicar denovo rsrsrs.
package pacote;
import outroPacote.Cavalo;
public class Teste
{
public static void main(String[] args){
Animal a = new Cavalo(); //Cavalo é publico logo, vc pode dar new no Cavalo
a.metodo(); //vc esta envocando o método de Animal que é protected e vc esta no mesmo pacote logo vc pode faze-lo
// o método envocado é o de Cavalo pq ele foi sobrescrito, e vc não invocou diretamente o de cavalo, pois este vc não teria acesso
Cavalo c = new Cavalo(); //por exemplo aki vc tem um cavalo
c.metodo(); //isso aki é impossivel, pois vc estaria incovando o metodo de outro pacote, o qual vc não enxerga
}
}
rod.atack: perfeito, porém não tem relação com a minha dúvida.
danieldomingues86: entendi o que você quis dizer, porém normalmente o metodo main não teria acesso ao metodo protected.
Lavieri:
[quote] a.metodo(); //vc esta envocando o método de Animal que é protected e vc esta no mesmo pacote logo vc pode faze-lo
// o método envocado é o de Cavalo pq ele foi sobrescrito, e vc não invocou diretamente o de cavalo, pois este vc não teria acesso[/quote]
Concordo, o compilador encherga somente o método de Animal.
Concluo que, em tempo de execução, o java executa o metodo de Animal e verifica se ele foi sobrescrito pela subclasse, caso sim, executa o metodo sobrescrito, ignorando se você possui acesso direto ou não.