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

Aula 5 - Modificadores de acesso - dúvida sobre as classes

Eu comecei a criar as classes segundo as primeiras aulas, mas algumas coisas ficaram diferentes, por exemplo a data e fiquei com dúvida em alguns métodos que tinham calculos e agora como eu faço calculo com métodos?

class Funcionario {
    String nome;
    String departamento;
    private double salario;
    String dataEntrada; 
    String rg;

    public void mostra() {
                System.out.println("Nome: " + this.nome);
                System.out.println("Departamento: " + getDepartamento());
                System.out.println("Salário: R$" + getSalario());
                //System.out.println("Data de entrada: " + getDataEntrada()); não achei o erro
                System.out.println("RG: " + this.rg);
                System.out.println("Ganho anual: R$" + getGanhoAnual());
    }

        public double getGanhoAnual() {
        return this.salario * 12;
    }

    public String getNome() {
        return this.nome;
    }

    public void setNome (String nome) {
        this.nome = nome;
    }

    public String getDepartamento() {
        return this.departamento;
    }

    public void setDepartamento (String departamento) {
        this.departamento = departamento;
    }

    public double getSalario() {
        return this.salario;
    }

    public void setSalario (double salario) {
        this.salario = salario;
    }

  /*  public Data getDataEntrada() {
        return this.dataEntrada;
    }

    public void setDataEntrada (Data dataEntrada) {
        this.dataEntrada = dataEntrada;
    }  não encontra*/

    public String getRg() {
        return this.rg;
    }

    public void recebeAumento(double aumento) {
        getSalario() += aumento; // como fica aqui, agora que são métodos?
    }

    public double calculaGanhoAnual() {
        return getSalario() * 12;
    }
}

class Empresa {

    private String nome;
    private String cnpj;
    private Funcionario[] funcionarios;
    private int livre = 0;

    public String getNome() {
        return this.nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCnpj() {
        return this.cnpj;
    }

    public void setCnpj(String cnpj) {
        this.cnpj = cnpj;
    }

    public Funcionario getFuncionario(int posicao) {
        return this.funcionarios[posicao];
    }

    void adicionar(Funcionario f) {
        this.funcionarios[this.livre] = f;
        this.livre++;
     }

    void mostraFuncionarios() {
        for (int i = 0; i < this.livre; i++) {
            System.out.println("Funcionário na posição: " + i);
            System.out.println("R$" + this.funcionarios[i].getSalario());
        }
    }

    void mostraTodasAsInformacoes() {
        for (int i = 0; i < this.livre; i++) {
         System.out.println("Funcionário na posição: " + i);
         this.funcionarios[i].mostra();
       }
    }

    boolean contem(Funcionario f) {
            for (int i = 0; i < this.livre; i++) {
                if (f == this.funcionarios[i]) {
                    return true;
                }
            }
            return false;
    }
}


class TestaEmpresa{


    public static void main(String[] args){
        Empresa novaempresa = new Empresa();
        novaempresa.funcionarios = new Funcionario[5];// essa linha reclama que o funcionario é private " has private acess in Empresa"

        for (int i = 0; i < 5; i++) {
            Funcionario f = new Funcionario();
            f.setSalario(1000 + i * 100);
            novaempresa.adicionar(f);           
        }
    }    
}


class TestaFuncionario {

    public static void main(String[] args) {
        Funcionario f1 = new Funcionario();

        f1.setSalario(1234);       
        f1.getFuncionario(2); // cannot find symbol
    }
}
10 respostas

Olá!

Como sua data está armazenada no tipo String, ao invés de Date, os métodos get() e set(String dataEntrada) devem retornar/receber String da seguinte forma:

public String getDataEntrada() {
    return this.dataEntrada;
}

public void setDataEntrada (String dataEntrada) {
    this.dataEntrada = dataEntrada;
}

Assim, o método mostra funcionará sem problemas:

public void mostra() {
    System.out.println("Nome: " + this.nome);
    System.out.println("Departamento: " + getDepartamento());
    System.out.println("Salário: R$" + getSalario());
    System.out.println("Data de entrada: " + getDataEntrada());
    System.out.println("RG: " + this.rg);
    System.out.println("Ganho anual: R$" + getGanhoAnual());
    }

Com relação ao ao método recebeAumento(double aumento) não sei se entendi. Está com algum erro? Me parece que está tudo correto. =)

Na classe TestaEmpresa, observe que você está instanciando uma Empresa. Ao tentar acessar o atributo funcionarios dessa classe, ele reclama que o atributo é private, ou seja, só pode ser acessado pela própria classe. Para aquela linha funcionar corretamente, seria necessário você utilizar um get(), assim:

public Funcionario[] getFuncionarios {
    return this.funcionarios;
}

Por fim, em TestaFuncionario, perceba que f1 é sua variável do tipo Funcionario. Ao fazer f1.getFuncionario(2), você estaria tentando chamar um método getFuncionario(int posicao) que recebe um int da classe Funcionario, mas o método é da classe Empresa. Portanto, se quisesse chamar esse método, teria que ter um objeto do tipo Empresa. =)

Espero que ter ajudo!

Bons estudos,

Fábio.

Obrigada, ficou uma dúvida ainda na criação de funcionários.

Nos execícios foi pedindo para ir modificando de private as variáveis, mas como fica a sintaxe de criar um novo funcionário se está private?

A minha dúvida é como eu vou criar novos funcionários se é private, não deu certo criando esse método?

public static void main(String[] args){
        Empresa novaempresa = new Empresa();
        novaempresa.getFuncionarios() = new Funcionario[5];

        for (int i = 0; i < 5; i++) {
            Funcionario f = new Funcionario();
            f.setSalario(1000 + i * 100);
            novaempresa.adicionar(f);
            //novaempresa.funcionarios[i].mostra();
        }

         novaempresa.getFuncionarios(2);

Surgiu outra dúvida, como eu faço alteração na Data, foi criada uma classe da Data em um arquivo separado, mas onde na classe do funcionário, eu faço a alteração.

Na classe da data, não identifica as variáveis, mês, dia e ano.

Me confundi nessas classes de empresa e funcionário, porque estava modificando o que já tinha sido feito nos exercícios anteriores.

Na classe TestaEmpresa, estava criando funcionários, certo?

Estava funcionando, só que depois que eu deixei private o array de funcionários, parou de gerar funcionários, não entendi o que eu devo fazer, porque não é um getter, nem setter se eu entendi direito, é um new de objeto.

Gisesonia,

Não sei se entendi muito bem suas dúvidas, mas vamos lá. Rs.

Primeiramente, quando você criava novos funcionários você fazia algo assim:

public static void main(String[] args) {
    Funcionario funcionario = new Funcionario();
    funcionario.nome = "Algum nome";
    funcionario.departamento = "Algum departamento";
   // E assim por diante...
}

A diferença de quando os atributos são privados é que não é possível acessá-los diretamente, ou seja:

public static void main(String[] args) {
    Funcionario funcionario = new Funcionario();
    funcionario.setNome("Algum nome");
    funcionario.setDepartamento("Algum departamento");
    // E assim por diante...
}

Perceba que o acesso é feito via métodos. Nesse caso, quando queremos definir os valores, chamamos os set(...).

Com relação à data havia ficado um pouco confuso, me avise se não for essa a sua dúvida, por favor:

Inicialmente, o primeiro código que você me mostrou tinha um atributo dataEntradacomo String, mas os get e set devolviam/recebiam Data. Isso estava dando um erro, pois os tipos não estavam de acordo. Quando pedi para você alterar tudo para String, foi por ter como base o tipo do atributo. Agora que você está me dizendo que criou uma classe Data para representá-la, o correto seria:

class Funcionario {
    private Data dataEntrada;

    public Data getDataEntrada() {
        return this.dataEntrada;
    }

    public void setDataEntrada(Data dataEntrada) {
        this.dataEntrada = dataEntrada;
    }

    // Restante da classe...

Para lhe dizer com mais detalhes, você poderia postar aqui sua classe Data? =)

Por fim, no seu código:

public static void main(String[] args) {
    Empresa novaEmpresa = new Empresa();
    novaEmpresa.getFuncionarios() = new Funcionario[5];

    // O laço do for aqui...

    novaEmpresa.getFuncionario(2);
}

Cuidado que você possui dois métodos com nome parecido: getFuncionario(...) e getFuncionarios(). O primeiro recebe um inteiro e o segundo não recebe nada. No código acima, na última linha, acho que você quer utilizar o singular, não? =)

Fábio

Entendi, mas devo estar colocando algum código em lugar errado, porque continua dando erro.

Erro de compilação: cnnot find symbol dia = this.dia... ano mês variable ano System.out.println (" A data...

uneexpected type method getFuncionarios( ) in class Empresa cannoy be aplied to given types novaempresa.getFuncionarios(2); required: no arguments found; int reason: actual and formal arguments lists differ in lenght

Não está criando 5 funcionários, não retornaria o 3º elemento do array?

Classe Funcionário.java

class Funcionario {
     String nome;
     String departamento;
    private double salario;
    Data dataEntrada; 
    String rg;

public void mostra() {
                System.out.println("Nome: " + this.nome);
                System.out.println("Departamento: " + getDepartamento());
                System.out.println("Salário: R$" + getSalario());
                System.out.println("Data de entrada: " + getDataEntrada());
                System.out.println("RG: " + this.rg);
                System.out.println("Ganho anual: R$" + getGanhoAnual());
    }

        public double getGanhoAnual() {
        return this.salario * 12;
    }

    public String getNome() {
        return this.nome;
    }

    public void setNome (String nome) {
        this.nome = nome;
    }

    public String getDepartamento() {
        return this.departamento;
    }

    public void setDepartamento (String departamento) {
        this.departamento = departamento;
    }

    public double getSalario() {
        return this.salario;
    }

    public void setSalario (double salario) {
        this.salario = salario;
    }

   public Data getDataEntrada() {
        return this.dataEntrada;
    }

    public void setDataEntrada (Data dataEntrada) {
        this.dataEntrada = dataEntrada;
    }

    public String getRg() {
        return this.rg;
    }

    public void recebeAumento(double aumento) {
        //getSalario() += aumento;
    }

    public double calculaGanhoAnual() {
        return getSalario() * 12;
    }
}


class Empresa {
    private String nome;
    private String cnpj;
    private Funcionario[] funcionarios;
    private int livre = 0;

    public String getNome() {
        return this.nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getCnpj() {
        return this.cnpj;
    }

    public void setCnpj(String cnpj) {
        this.cnpj = cnpj;
    }

    public Funcionario[] getFuncionarios() {
        return this.funcionarios;
    }

    public Funcionario getFuncionario(int posicao) {
        return this.funcionarios[posicao];
    }

    void adicionar(Funcionario f) {
        this.funcionarios[this.livre] = f;
        this.livre++;
     }

    void mostraFuncionarios() {
        for (int i = 0; i < this.livre; i++) {
            System.out.println("Funcionário na posição: " + i);
            System.out.println("R$" + this.funcionarios[i].getSalario());
        }
    }

    void mostraTodasAsInformacoes() {
        for (int i = 0; i < this.livre; i++) {
         System.out.println("Funcionário na posição: " + i);
         this.funcionarios[i].mostra();
       }
    }

    boolean contem(Funcionario f) {
            for (int i = 0; i < this.livre; i++) {
                if (f == this.funcionarios[i]) {
                    return true;
                }
            }
            return false;
    }
}


class TestaEmpresa{
      public static void main(String[] args){
        Empresa novaempresa = new Empresa();
        novaempresa.getFuncionarios() = new Funcionario[5];

        for (int i = 0; i < 5; i++) {
            Funcionario f = new Funcionario();
            f.setSalario(1000 + i * 100);
            novaempresa.adicionar(f);
             novaempresa.contem(f);
             novaempresa.getFuncionarios(2);
         }


         //novaempresa.mostraFuncionarios();
         //novaempresa.mostraTodasAsInformacoes();

    }    
}

Classe do exemplo de data do curso:

public class Data {

            public Data(int dia, int mes, int ano) {
                this.dia = dia;
                this.mes = mes;
                this.ano = ano;

                if (! isDataViavel(dia, mes, ano)) {
                    System.out.println("A data " + formata() + " não existe!");
                }
            }

            private boolean isDataViavel(int dia, int mes, int ano) {
                if (dia <= 0 || mes <= 0 || mes > 12 || ano <= 0) {
                    return false;
                }

                int ultimoDiaDoMes = 31; // por padrao são 31 dias
                if (mes == 4 || mes == 6 || mes == 9 || mes == 11 ) {
                    ultimoDiaDoMes = 30;
                } else if (mes == 2) {
                    ultimoDiaDoMes = 28;
                    if((ano % 400 == 0) || ((ano % 4 == 0) && (ano % 100 != 0))){
                        ultimoDiaDoMes = 29;
                    }
                }
                if (dia > ultimoDiaDoMes) {
                    return false;
                }

                return true;
            }
}

Isso existe?

novaempresa.getFuncionarios() = new Funcionario[5];

Porque eu só coloquei o get, porque ele não acessa, isso:

novaempresa.funcionarios[i].mostra();

Não me lembro porque mas estava assim:

novaempresa.funcionarios = new Funcionario[5];

Eu posso criar o funcionário sem isso, sem o .funcionarios?

Gisesonia,

Primeiramente, não se esqueça de colocar os atributos da classe Funcionario como private. Você já tem os get() e set():

public class Funcionario {
    private String nome;
    private String departamento;
    private double salario;
    private Data dataEntrada;
    private String rg;

    // Todos os seus Getters & Setters...
}

Perceba que você tem dois métodos bem parecidos, um getGanhoAnual() e um calculaGanhoAnual(). Você pode remover o primeiro e vamos utilizar somente o segundo. E já vamos deixar o recebeAumento(double valor) que está certinho, também. =)

public class Funcionario {
    // Atributos privados, Getters & Setters...

    public void recebeAumento(double aumento) {
        getSalario() += valor;
    }

    public double calculaGanhoAnual() {
        return getSalario() * 12;
    }
}

Dessa classe, só vai ficar faltando o método mostra():

public void mostra() {
    System.out.println("Nome: " + getNome());
    System.out.println("Departamento: " + getDepartamento());
    System.out.println("Salário: " + getSalario());
    System.out.println("Data de entrada: " + getDataEntrada().formata());
    System.out.println("RG: " + getRg());
    System.out.println("Ganho anual: " + calculaGanhoAnual());
}

Perceba que esse método está um pouco diferente na impressão da data de entrada. É importante lembrar que, como você armazenou a data num objeto do tipo Data, ao imprimí-la, não teremos um resultado muito agradável. Por ser um objeto, não uma String, ele chamará o método toString() que não implementamos, mas foi definido na classe mãe - Object. Por esse motivo estou chamando um método formata() que espero que me devolva a data formatada, no tipo String. =)

public class Data {
    private int dia;
    private int mes;
    private int ano;

    public Data(int dia, int mes, int ano) {
        this.dia = dia;
        this.mes = mes;
        this.ano = ano;

        if (!isDataViavel(dia, mes, ano) {
            System.out.println("A data " + formata() + " não existe!");
        }
    }

    private boolean isDataViavel(int dia, int mes, int ano) {
        if (dia <= 0 || mes <= 0 || mes > 12 || ano <= 0) {
            return false;
        }

        int ultimoDiaDoMes = 31;

        if (mes == 4 || mes == 6 || mes == 9 || mes == 11 ) {
            ultimoDiaDoMes = 30;
        } else if (mes == 2) {
            ultimoDiaDoMes = 28;

            if ((ano % 400 == 0) || ((ano % 4 == 0) && (ano % 100 != 0))) {
                ultimoDiaDoMes = 29;
            }
        }

        if (dia > ultimoDiaDoMes) {
            return false;
        }

        return true;
    }

    public String formata() {
        return dia + "/" + mes + "/" + ano;
    }

O seu primeiro problema, que você me apontou um erro de compilação está nessa classe Data. Se você observar, cannot find symbol dia... está nos dizendo que não foi possível encontrar dia. Talvez você tivesse se esquecido de declarar o atributo privado dia, bem como mes e ano. =)

Na segunda parte: unexpected type method getFuncionarios( ) ... required: no arguments..., está lhe dizendo que o método getFuncionarios()não espera nenhum parâmetro, entretanto você passou um inteiro (2). Cuidado que você possui dois métodos, conforme havia dito previamente: um getFuncionario(int posicao), que está no singular e recebe um inteiro, lhe devolvendo um Funcionario. O segundo, getFuncionarios(), no plural, não recebe nenhum parâmetro e devolve o array de todos os funcionários. =)

Para resolver esse problema, basta colocar no singular e não devemos ter mais problemas nessa parte. =)

E cuidado! Você acessava novaempresa.funcionarios = new Funcionario[5], quando o atributo funcionarios da classe Empresa não era privado. Quando você o modificou para privado, você teve que criar um get() para ele. =)

Quando você quer incluir um Funcionario na Empresa, você precisa primeiro inicializar o array. É o que você faz quando escreve novaempresa.getFuncionarios() = new Funcionario[5]. Você está apenas inicializando um array, com 5 espaços para objetos do tipo Funcionario, mas sem nenhum Funcionario de fato.

Depois disso, para incluir um funcionário, basta criá-lo e inserir no array, que é o que você está fazendo dentro do for da classe TestaEmpresa:

for (int i  = 0; i < 5 ; i++) {
    Funcionario f = new Funcionario();
   // Faz os Setters que quiser do funcionário...

    novaempresa.adicionar(f);
}

Espero ter ajudado. Se algo ainda ficar pouco nebuloso ou aparecer novas dúvidas, só postar aqui. =)

Fábio

Pessoal, tudo certo? muito cuidado com os getters e os setters. Vocês conseguiram entender o verdadeiro sentido de usar-los? lembre-se. Os getters e os setters tem como um objetivo generalizado proteger as regras de negócio da aplicação.

Para maiores informações existe uma postagem no blog referente aos getters e setters.

Getters e Setters - Blog da Caelum

podemos fechar o tópico? Caso tenham dúvidas não deixem de entrar em contato.

solução!

Gisesonia, nesse caso você não precisa trocar por método, pois a variável 'dataEntrada' está na mesma classe que o método 'mostra()'. Como ela é uma variável do tipo 'Data', que é um tipo da classe com mesmo nome, você só utilizaria o método, quando passar a utilizar 'private' nas variáveis da classe 'Data'. Como ainda não fizemos essa alteração na sequencia dos exercícios, vai funcionar utilizando a linha de código como estava anteriormente. Espero que tenha te ajudado.