Para saber qual metodo sera utilizado basta olhar para onde a referencia esta apontando.
Neste exemplo:
Funcionario ana = new Gerente();
ana.setSalario(3000.00);
System.out.println("Bonificacao do Funcionario: " + ana.getBonificacao());
O objeto ana tem como referência Funcionario que esta apontando para Gerente, por causa do polimorfismo sempre será chamado o método específico da classe que esta sendo apontada, ou seja, sera chamado getBonificacao() implementado em Gerente.
Se em nosso exemplo a classe Funcionario não for abstrata e tiver um método getBonificacao() com algum retorno especifico implementado, podemos instanciar um objeto desta maneira:
Funcionario ana = new Funcionario();
ana.setSalario(3000.00);
System.out.println("Bonificacao do Funcionario: " + ana.getBonificacao());
Agora ana tem como referência Funcionario que tambem esta apontando para Funcionario, com isso sera chamado getBonificacao() implementado em Funcionario.
O metodo getBonificacao() continua funciando, mesmo se a classe Funcionario for abstrada, basta ter a assinatura do método na classe.
public abstract class Funcionario {
public abstract double getBonificacao();
}
E na verdade setSenha() nao funciona por que nao esta implementada/assinada na classe Funcionario, caso contrario, funcionaria normalmente.