Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Esclarecimento sobre objeto passado como argumento

public class TesteReferencias {

        public static void main(String[] args) {

            Gerente g1 = new Gerente();
            g1.setNome("Marcos");
            g1.setSalario(5000.0);

            Funcionario f = new Funcionario();
            f.setSalario(2000.0);

            EditorVideo ev = new EditorVideo();
            ev.setSalario(2500.0);

            ControleBonificacao controle = new ControleBonificacao();
            controle.registra(g1);
            controle.registra(f);
            controle.registra(ev);

            System.out.println(controle.getSoma());

        }
}

No código acima estamos passando diversos tipos de funcionários para o método registra.

A seguir temos o código de ControleBonificacao:

public class ControleBonificacao {

        private double soma;

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

        public double getSoma() {
            return soma;
        }
}

Minha dúvida é: por que o método registra() invoca o método específico do objeto, e não o da superclasse? Para melhor entendimento, por exemplo, estou enviando o objeto Gerente g1 como argumento, porém o método registra() o recebe como uma referência Funcionário f, correto? Então por que o método não invoca o getBonificacao() da referência f?

1 resposta
solução!

Oi Fellipe, tudo bem?

Essa é uma das vantagens do polimorfismo, você poder referenciar objetos das classes filhas (Gerente e EditorVideo) através da classe mãe (Funcionario). E é isso que aconteceu nesse caso, tudo que o método registra sabe é que ele deve receber um funcionário. Agora, se esse funcionário é um gerente ou um editor de video, isso pouco importa, desde que eles herdem da classe Funcionario.

Uma regra que deve ser estabelecida antes de mais nada, como você citou: "o método registra() invoca o método específico do objeto, e não o da superclasse", ou seja, sempre que você tiver um método presente na classe mãe que é sobrescrita (@Override) na classe filha - como é o caso do getBonificacao - e esse método for chamado pelo objeto de uma das classes filhas, a implementação que será utilizada será a mais específica. Em outras palavras, a implementação presente na classe filha.

Quando o Gerente g1 é passado como parâmetro para o método registra, ele é recebido como Funcionário f. Mas o que isso significa? Significa que dentro daquela função ele será uma referência "f" do tipo Funcionario, podendo utilizar apenas métodos da classe Funcionario. Porém, o Java sabe que por baixo dos panos ele ainda é um g1 do tipo Gerente, portanto quando é chamado o getBonificacao(), um método já sobrescrito na classe Gerente, o programa já sabe que deve procurar o método mais específico dentro de Gerente para ser executado.

Espero ter ajudado, qualquer dúvida é só falar!

Bons estudos!