Dúvida no retorno de um valor

11 respostas
L

Bom pessoal estou fazendo um exercício bem simples que consiste em pegar o nome do Funcionário, suas horas trabalhadas e o valor de cada hora trabalhada. Eu somente preciso calcular o salário bruto do funcionario e retornar este valor , mas aí está o problema …

import java.util.ArrayList;
import java.util.Scanner;

public class Funcionario {
        
	    private static final int TAMANHO_LISTA = 3;
	   
	    private String sNome;
            private int iHorasTrabalhadas;
            private double dValorPorHorasTrab;
            private double dSalarioBruto;
	    
	    Scanner s = new Scanner(System.in);    
	    static ArrayList <Funcionario>array = new ArrayList<Funcionario>();
	   
	   // Métodos "get" da classe Funcionario.
	   public String getNome(){
		  
		   return sNome;
	   }
	   
	   public int getHorasTrabalhadas(){
		  
		   return iHorasTrabalhadas;
	   }
	   
	   public double getValorPorHorasTrab(){
		   
		   return dValorPorHorasTrab;
	   }
	   
	   //set e get do atributo "dSalarioBruto"
	   public void setSalarioBruto(double dVarSalBruto){
		   
		   this.dSalarioBruto = dVarSalBruto;
	   }
	   
	   public double getSalarioBruto(){
		   
		   return dSalarioBruto;
	   }


           //Contrutor de Funcionario.
	   public Funcionario(String sNome, int iHorasTrab, double dValorHoraTrab){
		  
		     this.sNome = sNome;
		     this.iHorasTrabalhadas = iHorasTrab;
		     this.dValorPorHorasTrab = dValorHoraTrab;
		     
	   }



         private double calculaSalarioBruto(){
		   //problema aqui... deveria retornar o valor...
		   return getHorasTrabalhadas() * getValorPorHorasTrab();
		   		   		   
	   }


         public void recebeDados(){
		   
		   for(int y = 0; y<TAMANHO_LISTA; y++){
			 
		       System.out.println("Nome do Funcionário: ");
		       String sVarNome = s.nextLine();s.nextLine();
		       System.out.println("Horas Trabalhadas: ");
		       int iVarHorasTrab = s.nextInt();
		       System.out.println("Valor por hora trabalhada: ");
		       double dVarValorPorHora = s.nextDouble();
		   
		       Funcionario obj = new Funcionario(sVarNome,iVarHorasTrab,dVarValorPorHora);
		       obj.setSalarioBruto(calculaSalarioBruto()); // aqui deveria inserir o valor retornado do método de cáculo de salário bruto para a inserção no "setSalarioBruto".
		       addFuncionario(obj);
		       
		   }
	   }


          public void imprimeFuncionario(){
		   
		   
		  for(int x=0; x<TAMANHO_LISTA; x++){   
		  
			  if(array.size() > 0){
			  
			     System.out.println("Nome: "+array.get(x).getNome());
			     System.out.println("Horas trabalhadas: "+array.get(x).getHorasTrabalhadas());;
			     System.out.println("Ganhos por hora: "+array.get(x).getValorPorHorasTrab());
			     System.out.println("Salário bruto: "+array.get(x).getSalarioBruto()); // não consigo calcular o salario bruto do funcionario.
			   			   
		     }
		     else{
			     System.out.println("Não existe funcionarios cadastrados.");
		     }
		  } 		   		   
	   }

 }// fim classe

Claro tem o método de adicionar funcionarios no array … mas este não é o caso … o erro está no método “calculaSalarioBruto()” ao meu ver … desculpe se meu código está confuso … é pq estou recém iniciando na programação … se alguém tiver algumas dicas de refatoração neste código serão bem vindas tb. ^^

Desde já obrigado pela ajuda !!
Marcos

11 Respostas

igor_jua

certo…mas qual é a exceção que ele ta gerando?

L

não é exceção e sim erro lógico… simplesmente não calcula o salário…

digamos que eu inseri alguns valores no array
Nome = marcos
horas horas trabalhadas = 40
Ganhos por hora = 3,50

na hora de imprimir a lista aparece assim …

Nome: Marcos
Horas trabalhadas: 40
Ganhos por hora: 3.5
Salário bruto: 0.0 <<< era para ter gerado o calculo

igor_jua

kra…meio estranho…
vc ja tentou fazer um debug para ver o que está acontecendo?

B

Você está multiplicando um int por um double. Passe o int getHorasTrabalhadas() para double que resolve o seu problema.

L

Tentei do meu jeito ^^(como disse sou novato rsrs)… fui colocando mensagens de “ok” só para ver se estava entrando nos métodos corretamente, até chega a entrar no método de cálculo, criei uma variável temporária só para ver se pelo menos calculava alguma coisa mas nem cacular ele cacula ^^

igor_jua

vc tem msn??
se tiver me add aí pra gente resolver isso ok?

ViniGodoy

A menos que ele esteja colocando um valor quebrado e menor que zero no campo inteiro, não haverá problema nesse caso.

Já que você pediu dicas de refatoração. lá vai:

  1. Use listas sempre através da interface, não da classe concreta. Isso facilita muito na hora de trocar de lista:
static List <Funcionario>array = new ArrayList<Funcionario>();
  1. Não coloque letras identificando o tipo da variável no nome da variável. Há muito tempo isso deixou de ser necessário e, como a própria Microsoft (que era fã disso) notou, essa notação gera muito mais problemas do que benefícios. A exceção é apenas para componentes de interface gráfica, onde prefixos geralmente são usados para diferencia-los entre si (até pq, muitos componentes terão o mesmo nome: lblNome, txtNome).

  2. Pense sete milhões de vezes antes de definir um atributo como static. Se for uma lista, pense 70 milhões de vezes, não sete.

  3. Remova o atributo dSalarioBruto. Também remova o método calculaSalarioBruto(). Deixe a lógica do cálculo do salário bruto diretamente no método getSalarioBruto(). Também remova o método setSalarioBruto(). Esse vira um bom exemplo de atributo automaticamente calculado, e read-only.

  4. A constante TAMANHO_LISTA deve ser usada somente no momento da criação da lista. Na hora de percorrer, use os atributos array.size() ou array.length. Ou, melhor do que isso, use um for each:

public static void imprimeFuncionarios() { if (array.size() == 0) { System.out.println("Não existe funcionário cadastrado."); return; } for (Funcionario f : array) { System.out.println("Nome: "+ f.getNome()); System.out.println("Horas trabalhadas: "+ f.getHorasTrabalhadas());; System.out.println("Ganhos por hora: "+f.getValorPorHorasTrab()); System.out.println("Salário bruto: "+f.getSalarioBruto()); } }

  1. Divida seu programa em duas classes. Na primeira, deixe só a lógica do funcionário (sem a lista e sem a impressão). Na segunda, crie a lista de funcionários e faça as lógicas de leitura e impressão dos dados. Quanto mais coesão tiverem suas classes, melhor.
L

Tentei o que você disse e mesmo assim continuo com o erro :?

igor_jua:
vc tem msn??
se tiver me add aí pra gente resolver isso ok?

meu msn é [email removido]

L

A menos que ele esteja colocando um valor quebrado e menor que zero no campo inteiro, não haverá problema nesse caso.

Já que você pediu dicas de refatoração. lá vai:

  1. Use listas sempre através da interface, não da classe concreta. Isso facilita muito na hora de trocar de lista:
static List <Funcionario>array = new ArrayList<Funcionario>();
  1. Não coloque letras identificando o tipo da variável no nome da variável. Há muito tempo isso deixou de ser necessário e, como a própria Microsoft (que era fã disso) notou, essa notação gera muito mais problemas do que benefícios. A exceção é apenas para componentes de interface gráfica, onde prefixos geralmente são usados para diferencia-los entre si (até pq, muitos componentes terão o mesmo nome: lblNome, txtNome).

  2. Pense sete milhões de vezes antes de definir um atributo como static. Se for uma lista, pense 70 milhões de vezes, não sete.

  3. Remova o atributo dSalarioBruto. Também remova o método calculaSalarioBruto(). Deixe a lógica do cálculo do salário bruto diretamente no método getSalarioBruto(). Também remova o método setSalarioBruto(). Esse vira um bom exemplo de atributo automaticamente calculado, e read-only.

  4. A constante TAMANHO_LISTA deve ser usada somente no momento da criação da lista. Na hora de percorrer, use os atributos array.size() ou array.length. Ou, melhor do que isso, use um for each:

public static void imprimeFuncionarios() { if (array.size() == 0) { System.out.println("Não existe funcionário cadastrado."); return; } for (Funcionario f : array) { System.out.println("Nome: "+ f.getNome()); System.out.println("Horas trabalhadas: "+ f.getHorasTrabalhadas());; System.out.println("Ganhos por hora: "+f.getValorPorHorasTrab()); System.out.println("Salário bruto: "+f.getSalarioBruto()); } }

  1. Divida seu programa em duas classes. Na primeira, deixe só a lógica do funcionário (sem a lista e sem a impressão). Na segunda, crie a lista de funcionários e faça as lógicas de leitura e impressão dos dados. Quanto mais coesão tiverem suas classes, melhor.

Obrigado pelas dicas … estou tentanto aprender a programar usando refatoração desde o início , também já tentei usar TDD mas ainda esta muito acima do meu nível :smiley: … quem sabe mais para frente ^^

L

Consegui remover o problema seguindo estes passos que o ViniGodoy disse… não sei como mas deu certo :wink:

Obrigado a todos pelas dicas !!

ViniGodoy

Porque sua linha estava:

obj.setSalarioBruto(calculaSalarioBruto());

Quando o correto era:

obj.setSalarioBruto(obj.calculaSalarioBruto());

Veja o que você fazia. Existia 2 funcionários, o this e o obj (criado dentro do método).
Você chamava calculaSalarioBruto() do this, e atribuia o valor ao setSalarioBruto() de obj.

Se você tornar o método recebeDados() static, esse problema se torna evidente. Aliás, por uma questão de coerência, geralmente os métodos que lidam com os atributos static da classe (como sua lista) também são static. Isso também te poupa de criar um funcionario, com a única finalidade de chamar o método recebeDados. Torne-o static e você poderá chama-lo assim:

Funcionario.recebeDados();

A minha dica 4 não só deixa o código mais simples, como também evita essa possível confusão. Veja bem, da forma que eu propus, é impossível definir um salário bruto diferente do que o calculado pela fórmula e, portanto, impossível inserir erros como aquele.

Criado 30 de junho de 2009
Ultima resposta 30 de jun. de 2009
Respostas 11
Participantes 4