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

Construtor da classe gerente

Minha duvida é a seguinte: se na classe funcionário eu posso criar um construtor de forma que ja colete as informações sem necessitar do getter, porque não funciona o mesmo com o gerente já que ele herda a classe funcionário?

Para expressar melhor, segue o código que escrevi:

    Funcionario(String nome, String cpf, double salario){
        this.nome = nome;
        this.cpf = cpf;
        this.salario = salario;
    }

Já com a classe gerente fiz o seguinte:

    Gerente(String nome, String cpf, double salario, int senha) {
        super.setCpf(cpf);
        super.setNome(nome);
        super.setSalario(salario);
        this.senha = senha;
    }

mas não compila (exibe um erro).

Em meio varias tentativas de fazer essas peças se encaixarem, acabei conseguindo fazer com que o eclipse auto completasse de forma correta:

    Gerente(String nome, String cpf, double salario, int senha) {
        super(nome, cpf, salario);
        this.senha = senha;
    }

e assim o resto do código funcionou numa boa.

Minhas duvidas são:

1º: O que aquele

        super(nome, cpf, salario);

de fato faz.

2º: Porque da primeira tentativa não funcionou.

1 resposta
solução!

Oi Samuel, tudo bem?

Esse é um erro bem comum para desenvolvedores, mas que pode ser facilmente evitado assim que entendemos como o construtor se comporta com a herança. Praticamente qualquer dúvida, independente da tecnologia relacionada, tem suas respostas na documentação. Com Java não é diferente, vendo a documentação da palavra-chave super:

"Se um construtor não invoca explicitamente um construtor de superclasse, o compilador Java insere automaticamente uma chamada para o construtor sem argumento da superclasse. Se a superclasse não tiver um construtor sem argumentos, você receberá um erro em tempo de compilação."

Ok, mas o que isso quer dizer?

Como será explicado na aula 4 do curso, ao criarmos a classe Gerente que herda da classe Funcionario, o compilador insere automaticamente um construtor invisível que invoca o construtor da classe mãe através da palavra-chave super(), ou seja, por baixo dos panos é isso que acontece:

public class Gerente extends Funcionario {
    public Gerente() {
        super(); //chamando construtor de  Funcionario
    }
}

Portanto, se olharmos para o seu primeiro código, é isso que vemos:

Gerente(String nome, String cpf, double salario, int senha) {
        super.setCpf(cpf);
        super.setNome(nome);
        super.setSalario(salario);
        this.senha = senha;
    }

Porém, na realidade, é isso que acontece:

Gerente(String nome, String cpf, double salario, int senha) {
        super();
        super.setCpf(cpf);
        super.setNome(nome);
        super.setSalario(salario);
        this.senha = senha;
    }

Existe uma chamada implícita ao construtor padrão (sem argumentos) da classe Funcionario, o problema é que o construtor padrão sem argumentos da classe Funcionario deixou de existir (ou melhor, foi substituído) a partir do momento em que você criou esse outro construtor:

Funcionario(String nome, String cpf, double salario){
        this.nome = nome;
        this.cpf = cpf;
        this.salario = salario;
    }

E como vimos na documentação:

"Se a superclasse não tiver um construtor sem argumentos, você receberá um erro em tempo de compilação."

Como resolver isso? Simples, temos duas maneiras:

1. Criar um construtor vazio na classe Funcionario para que o seu primeiro código não dê nenhum erro ao tentar chamar o construtor padrão sem argumentos da classe mãe:

public class Funcionario {

    //Código omitido

    //Construtor sem argumentos que receberá a chamada de super()
    public Funcionario() {    
    }

    public Funcionario(String nome, String cpf, double salario) {
        this.nome = nome;
        this.cpf = cpf;
        this.salario = salario;
    }

Fazendo isso, quando o construtor de Gerente usar o super() por baixo dos panos, esse código irá rodar:

Gerente(String nome, String cpf, double salario, int senha) {
        super.setCpf(cpf);
        super.setNome(nome);
        super.setSalario(salario);
        this.senha = senha;
    }

2. Adicionar uma chamada explícita ao construtor com argumentos da classe mãe (o que você fez):

public class Gerente extends Funcionario{

    //Código omitido

    public Gerente(String nome, String cpf, double salario) {
        super(nome, cpf, salario);
    }

Aqui, ao passarmos parâmetros dentro de super(nome, cpf, salario), estamos declarando explicitamente que não queremos o construtor padrão da classe Funcionario, mas sim o construtor que recebe esses exatos parâmetros!

Lembrando:

"Se um construtor não invoca explicitamente um construtor de superclasse, o compilador Java insere automaticamente uma chamada para o construtor sem argumento da superclasse."

Bom, aqui estamos invocando explicitamente o construtor da superclasse através do super(nome, cpf, salario).

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

Bons estudos!!