Oi Gabriel, tudo bem?
Realmente, isso é uma regra. Se fizermos algo como Funcionario g = new Gerente()
, tudo que o Java enxerga inicialmente é que o tipo do objeto g
é Funcionario
, portanto teremos acesso apenas aos métodos de Funcionario
. Levando isso em consideração, sabemos que não temos acesso aos métodos exclusivos da classe Gerente
, como o setSenha
e o autentica
, já que eles não foram herdados da superclasse Funcionario
. Mas veja bem, também temos o método getBonificacao
que foi herdado da superclasse Funcionario
e é aqui que a coisa fica interessante, se usarmos a referência g
para chamar esse método como em g.getBonificacao()
, o método chamado é o método da classe Gerente
, e não a do Funcionario
, o que contradiz aquela nossa primeira regra de levar em consideração apenas o tipo do objeto, correto?! Bom, nem sempre.
No polimorfismo, temos uma outra regrinha que diz que o método invocado é sempre o método mais específico. Ou seja, como o getBonificacao
está presente tanto na superclasse Funcionario
como na subclasse Gerente
(já que ele foi sobrescrito aqui), o Java vai buscar pelo getBonificacao
mais específico, checando se na classe Gerente
temos uma outra versão desse mesmo cara para, em seguida, chamá-lo no lugar do método da superclasse.
Isso, claro, só funciona pois Gerente
herda de Funcionario
, o que mostra que Gerente
nada mais é que um Funcionario
com mais particularidades, ou melhor dizendo, um Funcionario
mais específico! :)
Espero ter ajudado, qualquer dúvida estou à disposição!
Bons estudos!!