Olá Camila, tudo bem com você?
O que acontece é que enquanto estamos escrevendo o nosso código, o Java enxerga apenas o TIPO da referência - como o Funcionario
, por exemplo.
Agora, ao executarmos o nosso programa, é considerado apenas o que está DENTRO dessa referência! Em outras palavras, embora esteja correto dizer que "quem define o que podemos chamar é a referência", o método a ser chamado é definido em tempo de execução de acordo com o tipo do objeto. Portanto, no caso do Veiculo m = new Moto()
, apesar da referência ser do tipo Veiculo
, o tipo do objeto que será considerado na execução do programa é a Moto
!!
Essa é a forma como o Polimorfismo é aplicado em Java, como o seu nome já diz: poli = muitas, morphos = formas. Então, embora as referências m e c do exercício sejam do tipo Veiculo
, dependendo de suas implementações (Moto ou Carro
), seus comportamentos podem mudar durante a execução do programa! ;)
Algo que pode deixar mais claro é analisando o seguinte exemplo:
Funcionario g = new Gerente();
Apesar de estarmos declarando que a referência g é um Funcionario
, nós sabemos que na verdade não existe nenhum Funcionario
de verdade nesse programa já que, por de baixo dos panos, nós estamos instanciando apenas o Gerente
lá na memória da nossa máquina! E se é assim, então não tem como chamarmos o método m.liga()
de Funcionario
sendo que nunca criamos o objeto dele.
Espero que isso ajude. Se ficou alguma dúvida é só avisar!
Abraços e bons estudos!!