1
resposta

Métodos de objetos do tipo genérico chamando métodos do tipo específico

Para código abaixo, dependendo de quem o chama, são chamados diferentes "getBonificacao".

public void registra(Funcionario funcionario) {
    double bonificacao = funcionario.getBonificacao();
    this.soma += bonificacao;
}            

Por exemplo, quando executamos o código abaixo

Funcionario funcionario = new Funcionario();
funcionario.setSalario(2000);

EditorVideo editor = new EditorVideo();
editor.setSalario(3000);

ControleBonificacao controle = new ControleBonificacao();
controle.registra(funcionario);
controle.registra(editor);

Temos que os seguintes métodos são executados (em suas respectivas classes):

public double getBonificacao() {
    System.out.println("Chamando bonificação do funcionário");
    return this.salario * 0.1;
}

public double getBonificacao() {
    System.out.println("Chamando bonificação do editor de vídeo");
    return super.getBonificacao() + 100;
}

Mas por que isso ocorre? O compilador entende que estamos passando como parâmetro na função "registra" um objeto do tipo Funcionario, certo? Dessa forma, deveria ser chamado apenas o método do Funcionario, não das demais classes.

Ou sabendo que foi passado um objeto de um tipo mais específico como parâmetro para a função "registra" é feita alguma referência para a classe específica? Isso, pelo menos para mim, não ficou claro. Se souberem onde posso buscar mais sobre isso, agradeço!

1 resposta

Cara, primeiramente, saudações EACHianas!!

Acho que vai ser um pouco complexo de explicar por aqui, então qualquer dúvida que tiver, pode responder novamente que eu tento de outro jeito.

No caso de herança, quando cria uma classe derivada exemplo EditorVideo que extends Funcionário, você está passando todo o comportamento de Funcionário, para EditorVideo. Porém você pode querer (como no caso da bonificação) alterar o comportamento de um dos métodos herdados. Fazendo isso quando você chama o controle.registra(editor) você está chamando na verdade o método que você sobrescreveu em Editor, não do Funcionário.

Isso é importante para deixar o seu código genérico e não precisar repetir código para tratar objetos semelhantes (em termos de estrutura e que variam apenas na implementação).

Pensando nesse seu caso ainda se você tivesse uma classe Gerente e que também herdasse de Funcionário e tivesse implementação própria do getBonificação() você poderia fazer o seguinte:

Funcionario func = new Funcionario();
Funcionario gerente = new Gerente();
Funcionario editor = new Editor();

E aí esse seu método registra (no controle) apesar de receber um funcionário, rodaria as 3 implementações diferentes de getBonificação() de cada um dos tipos.