Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Polimorfismo na prática

Boa tarde, Gostaria de saber como funciona a diferença dos seguintes códigos na pratica. Não estou conseguindo entender o que muda de um para o outro.

Ate o momento a unica coisa que muda é o acesso aos atributos do Gerente.

Funcionario teste = new Gerente();


Gerente teste = new Gerente();

desde já agradeço

3 respostas
solução!

Oi André, tudo bem?

A grande sacada de conseguir fazer

Funcionario teste = new Gerente();

É que conseguimos fazer um código muito mais reaproveitável, pois trabalhamos de maneira mais abstrata. Podemos trabalhar com qualquer classe que herde de Funcionario. Podemos definir um método em Funcionário que todos os filhos sobrescrevem, e na prática, nos referenciaremos pelo método de Funcionário, porém será executado, em tempo de execução, o método da classe herdeira de funcionário.

Ola Otávio, aproveitando a dúvida do André, também estou com dificuldades em entender, teria algum exemplo prático para melhor entendimento? Pois não vejo qual a vantagem ou desvantagem de se escrever o código desta forma:

Funcionario teste = new Gerente();

Obrigado

Otávio, obrigado pela explicação, fez mais sentido para mim. Caso alguém não tenha entendido, achei uma resposta em um tópico, muito boa para esclarecer, segue: " Olá Rogério,

Imagine que você tenha o código abaixo:

class Funcionario {
    double calcSalario() {
        return valorDia*22;
    }
}

class Gerente extends Funcionario {
    @Override
    double calcSalario() {
        return super.calcSalario()*1.2;
    }
}

A situação é a seguinte: Gerente é um funcionário, porém com um cálculo de salário diferenciado, neste caso, ganha 20% em cima do salário base.

Agora imagina que vc tenha um array de funcionários, que poderão ser da classe Funcionario ou Gerente (ou Diretor, Presidente, etc). Se eu quisesse imprimir o salário de todos os funcionários, poderia ter o seguinte código:

class Relatorio {
    public void imprimirSalarios(Funcionario[] funcionarios) {
        for (Funcionario f: funcionarios) {
            System.out.println(f.calcSalario());
        }
    }
}

Veja que devido ao Polimorfismo, quando o método calcSalario é chamado dentro do for (classe Relatorio), se a instância for de Funcionario a implementação de Funcionario será chamada, mas se a instância for de Gerente então a implementação de Gerente será chamada.

Em C++ o método calcSalario() precisaria ser virtual para termos este comportamento igual ao Java, caso contrário o método chamado iria depender do tipo da referência (Funcionario ou Gerente), por exemplo:

class Funcionario {
    double calcSalario();
}

class Gerente: public Funcionario {
    double calcSalario();
}

Funcionario *f = Gerente();
f->calcSalario(); // Chama a implementacao de Funcionario

Gerente *g = Gerente();
g->calcSalario(); // Chama a implementacao de Gerente

Mas se calcSalario em Gerente fosse definida como virtual, sempre seria chamado a implementação do tipo correto, por exemplo:

class Gerente: public Funcionario {
    virtual double calcSalario();
}

Funcionario *f = Gerente();
f->calcSalario(); // Chama a implementação de Gerente

Espero que tenha ajudado.

Att. "