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

Implementação de polimorfismo

Olá galera.

estou em dúvida na implementação de polimorfismo no código abaixo:

Funcionario teste = new Gerente();

Na pratica, o que muda na implementação desse?

Gerente teste = new Gerente();

Mesma sendo citado em várias vezes na aula e eu entendo o conceito de polimorfismo aplicado nas classes, esse acima me confundiu um pouco.

Obrigado :D

2 respostas

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.

solução!

Eduardo já explicou bem acima, vou tentar explicar diferente, apenas para consolidar =D.

Funcionario teste =  new Gerente();  // Caso 1
Gerente teste = new Gerente();   // Caso 2

Como você mesmo escreveu a diferença está na referência para o objeto. O objeto em sí sempre será um Gerente.

Entretanto como no Caso 1 a referencia é do tipo Funcionário, fazendo o uso dela você não poderá invocar diretamente métodos que foram criados dentro da classe Gerente (mesmo o objeto sendo um Gerente), pois a referência é da classe Funcionário e nela o compilador irá vasculhar apenas por método existentes na classe Funcionário (e não na classe Gerente).

"Então qual a vantagem?" - A vantagem não está em poder ou não invocar os método, a vantagem se encontra em você poder utilizar a referência "teste", explicitada no Caso 2, como parâmetro de métodos os quais exigem obrigatóriamente que o tipo da referência seje do tipo Funcionário.

Em outras palavras:

public void umMetodoQualquer (Funcionario f1) {
    // Uma aplicação qualquer
}

No código acima repare que o método exige que "f1" seje uma referência do tipo Funcionário, porém você pode utilizar do "teste", do Caso 2, como parâmetro e irá funcionar normalmente, pois no fundo Gerente é um Funcionário, e além disso os métodos inclusos na classe Gerente irão ser executados caso sejam invocados por este código acima. Esta é a vantagem do polimorfismo =)).