4
respostas

Funcionario g1 = new Gerente(); | Como usar os metodos de Gerente?

Pessoal, não estou conseguindo entender a explicação do professor sobre essa questão do Funcionario g1 = new Gerente();

Pois se eu uso tanto o Funcionario g1 = new Gerente(); quanto o Gerente g1 = new Gerente(); em ambos os casos eu vou poder usar normalmente o codigo de soma de bonificação baixo:

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;
        }
}

Porém se eu usar o Funcionario g1 = new Gerente(); eu saio perdendo, pois eu não vou poder usar os métodos da classe Gerente, portanto eu não estou entendendo a real vantagem de usar o Funcionario g1 já que os métodos especificos da classe Gerente não vão servir para nada, vão ficar obsoletos. Então, a principio, me parece ser mais vantajoso usar Gerente g1, já que ele é mais flexivel. Minha dúvida é, se eu usar o Funcionario g1 = new Gerente existe uma maneira de usar os métodos especificos somente da classe Gerente?

(Por fim, mesmo que haja uma maneira do Funcionario g1 usar os métodos especificos da classe Gerente, ainda sim, o Funcionario g1 não será de fato uma vantagem, pois nesse caso ele vai apenas se igualar com Gerente g1. Eles serão apenas uma maneira diferente de fazer a mesmissima coisa).

4 respostas

Olá Maísa, tudo bem?

Excelente pergunta essa que você levantou aqui!

O conceito que estamos vendo nessa situação é como utilizamos o Polimorfismo, e é extremamente importante entender como ele pode ser útil para nós.

O exemplo que você trouxe é excelente para entendermos isso... então vamos lá...

Note que a classe Gerente herda da classe Funcionario, então todos os métodos e atributos que um funcionário possui, um gerente também irá possuir, certo?

Além disso, as subclasses (ou classes filhas), podem reescrever métodos da superclasse (ou classe mãe), como vemos no caso da bonificação do gerente, que é diferente dos demais funcionários.

Então o que acontece quando instanciamos um novo gerente dessa forma abaixo?

Funcionario g1 = new Gerente();

Será que perdemos os métodos da classe gerente por termos utilizado dessa forma?

O que acontece nesse caso, é que estamos utilizando uma variável de tipo mais genérico para armazenar uma referência ao objeto do tipo Gerente!

É isso que o Polimorfismo nos traz... a capacidade de um objeto poder ser referenciado de várias formas. Nesse caso poderíamos referenciar o objeto Gerente tanto como um Funcionario como um Gerente, pois o Gerente (subclasse) obrigatoriamente é também um Funcionario (superclasse).

OBS:(cuidado, polimorfismo não quer dizer que o objeto fica se transformando, muito pelo contrário, um objeto nasce de um tipo e morre daquele tipo, o que pode mudar é a maneira como nos referimos a ele).

O que pode acontecer de fato, é que talvez você "não consiga" acessar alguns métodos da classe Gerente num primeiro momento, se a utilizar dessa maneira. O mais comum é que nessa situação você realmente utilize:

Gerente g1 = new Gerente();

Apenas em alguns poucos casos nós teríamos que utilizar a referência do tipo Funcionario, e nesses casos ainda assim poderíamos acessar os métodos da classe Gerente por meio de Casting, mas isso não é o mais comum, e também é mais trabalhoso.

Então em que caso isso seria útil para nós?

A situação que costuma acontecer é a que temos um método que recebe um argumento do tipo Funcionario:

 class ControleDeBonificacoes {
        private double totalDeBonificacoes = 0;

        public void registra(Funcionario funcionario) {
            this.totalDeBonificacoes += funcionario.getBonificacao();
        }

        public double getTotalDeBonificacoes() {
            return this.totalDeBonificacoes;
        }
    }

Nesse caso criamos um método que tem como parâmetro um Funcionario. Para não reescrevermos o mesmo método mais de uma vez, podemos nos utilizar do Polimorfismo, passando todos os funcionários utilizando a referência mais genérica.

Esses conceitos podem ser bem difíceis de entender a primeira vista, é super normal... mas você está indo muito bem!

Com o treino e exercícios você vai pegar muito bem esse assunto, não se preocupe.

Te recomendo também ler a apostila da Caelum sobre Java e Orientação a objetos, pode te ajudar a entender mais a respeito de vários conceitos.

Apostila de Java - Caelum: Polimorfismo

Sempre que tiver dúvidas, pode contar conosco! 😉

Oi Guilherme, obrigada por responder.

Mas nesse exemplo que o professor passou, eu consigo usar a class ControleDeBonificacoes que vc postou acima tanto colocando o funcionario g1 = new Gerente(); quanto o Gerente g1 = new Gerente(); . Eu testei e ambos funcionaram normalmente sem ter a necessidade de escrever o mesmo metodo varias vezes para cada tipo de funcionario. Acontece que nesse exemplo do professor quando eu coloco o funcionario g1 = new Gerente(); eu saio perdendo, pois eu consigo usar class ControleDeBonificacoes masss ao mesmo tempo não consigo acessar os métodos e atributos que pertecem somente a classe Gerente. Já se eu coloco Gerente g1 = new Gerente();* eu posso usar a class ControleDeBonificacoes normalmente e ainda por cima consigo usar os atributos e métodos espeficifcos da classe Gerente. Então nesse exemplo usar funcionario g1 = new Gerente(); não me parece ser util. Não sei se conforme as aulas forem caminhando vai haver alguma situação que usar a forma funcionario g1 será realmente vantajosa, mas nesse momento a real vantagem de usar funcionario g1 ou inves de gerente g1 ainda não ficou clara para mim.

Entendi, Maísa.

Como te falei, há casos em que vai ser útil para nós utilizarmos um tipo mais genérico, especialmente quando nós não sabemos o que vamos passar como parâmetro para o método.

Nem todos os casos vão nos exigir isso... como você falou, geralmente é mais útil utilizarmos o tipo mais específico, é o mais comum. O único caso em que seria útil para nós utilizarmos o tipo mais genérico, seria para aproveitar um método que é utilizado por vários tipos específicos.

Sobre ter a possibilidade de utilizar os métodos da classe Gerente, existe sim... Como te falei, podemos fazer o casting, que nos possibilita utilizar os métodos da classe Gerente, mesmo que tenha sido instanciado como um objeto do tipo Funcionario.

Nesse exemplo que estou te mostrando abaixo, estou utilizando um método específico da classe Gerente, o método aumentaSalario por meio do casting...

Método aumentaSalario

Casting

Mas vale lembrar que não é o comum, ter que fazer casting dessa forma.

Inclusive, encontrei uma excelente explicação para a mesma dúvida que você levantou aqui, de outro companheiro nosso da Alura, e creio que ela também vai te ajudar 😄

Tópico sobre casting

Neste tópico ele explica um pouco a respeito do casting e utiliza ele de uma forma diferente da que eu te apresentei na imagem acima... vale a pena conferir.

O importante é que você tenha entendido o conceito dos tipos genéricos e específicos e que em certas situações podemos utilizar um ou outro. Como te falei antes, não é o costume que façamos casting para utilizar dessa forma, então não precisa se preocupar tanto com essa utilização, o essencial é que você tenha entendido a lógica do polimorfismo, e com o tempo você vai se acostumando com essas situações específicas.

E sempre que tiver dúvidas, pode contar com a gente!

Bons estudos!

Muito obrigada pela ajuda Guilherme :)