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!!