[RESOLVIDO] Muitas dúvidas com OOP!

[b]Bom dia pessoal!

Galera, estou pela primeira vez implementando um programa JAVA com a temida ( pelo menos para mim auhauhauhahu ), OOP!
O meu professor começou a passar conceitos de OOP, e seus agregados em aula, e acabou pedindo para construirmos uma classe “ControleFuncionarios”, uma super classe “Empregado” e trés classes estendidas de empregado rotuladas como “Gerente”, “Programador” e finalmente “Secretaria”.
Eu comecei a implementar meu código como segue abaixo: [/b]

[code]import javax.swing.JOptionPane;

public class ControleFuncionarios {

public static void main(String[] args) {

	int continua = 0, contador=0;
	int tipo=0;
	String situacao;
	
	int numGerentes=0, numSecret=0, numProgram=0;

	Empregado[] empregados = new Empregado[100];

	String[] tipoFunc = {"GERENTE", "SECRETARIA", "PROGRAMADOR"};

	do {
		situacao = " Existem " + contador + " Empregados cadastrados de um total de " + empregados.length + 
		"\n sao:\n" + 
		numGerentes + " Gerentes\n" +
		numSecret + " Secretarias\n" +
		numProgram + " Programadores\n" +
		"\n Deseja cadastrar um novo empregado? ";	
		
		continua = JOptionPane.showConfirmDialog(null, situacao );
		
		if (continua==0) {
			
			String nome = JOptionPane.showInputDialog(" Informe o nome do novo empregado ");
			String sobrenome = JOptionPane.showInputDialog(" Informe o seu sobrenome " );
			
			String ano = JOptionPane.showInputDialog("Informe o ano de admissao de " + nome);
			int a = Integer.parseInt( ano );   
	          
			String mes = JOptionPane.showInputDialog("informe o mes de admissao " + nome);
			int m = Integer.parseInt(mes);
			
			String dia = JOptionPane.showInputDialog("Informe o dia de admissao de " + nome);
			int d = Integer.parseInt(dia);
			
			String tel = JOptionPane.showInputDialog("Informe o telefone de " + nome);
			
			String cpf = JOptionPane.showInputDialog("Informe o cpf de " + nome);
			int c = Integer.parseInt(cpf);
			
			String anoN = JOptionPane.showInputDialog("Informe o ano de nascimento de " + nome);
			int aN = Integer.parseInt(anoN);
			
			String mesN = JOptionPane.showInputDialog("Informe o mes de nascimento de " + nome);
			int mN = Integer.parseInt(mesN);
			
			String diaN = JOptionPane.showInputDialog("Informe o dia de nascimento de " + nome);
			int dN = Integer.parseInt(diaN);
			
			Empregado e = new Empregado(nome, sobrenome, a, m, d, tel, c, aN, mN, dN);
			
			tipo = JOptionPane.showOptionDialog(null, nome + " e um? ", " Cadastro ", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, tipoFunc, "GERENTE");
			
			if(tipo == 0) {  
				// informou que é GERENTE
				empregados[contador] = new Gerente(nome, sobrenome, a, m, d, tel, c, aN, mN, dN);
				numGerentes++;
				
				for(int i = 0; i < empregados.length; i++){
					if (empregados[i] instanceof Gerente);
					Gerente p = (Gerente) empregados[i];
				}
				
				p.setNivelPrograma nior";
				psetNome = " jose ";
				
			} else if(tipo == 1) {
				// informou que é SECRETARIA
				empregados[contador] = new Secretaria(nome, sobrenome, a, m, d, tel, c, aN, mN, dN);
				numSecret++;
				
			} else {
				// informou que é PROGRAMADOR
				empregados[contador] = new Gerente(nome, sobrenome, a, m, d, tel, c, aN, mN, dN);
				numProgram++;
			}
			
			contador++;	// incrementa o numero de funcionarios cadastrados
		}
		
	} while (continua == 0);

	System.out.println("LISTANDO NA CONSOLE OS REGISTROS DO VETOR DE FUNCIONARIOS.... ");
	
	for (int i = 0; i < contador; i++) {
		System.out.println("EMPREGADO NO REGISTRO ["+i+"] = " + empregados[i].getNome()+ empregados[i].getSobreNome());
	}
	
}

}[/code]

A superclasse:

[code]import java.util.Date;

import java.util.GregorianCalendar;

public class Empregado {

private String nome;

private String sobrenome;

private double salario;

private final Date dataAdmissao;

private String telefone;

private int cpf;

private Date nascimento;



public Empregado(String novoEmpregado, String sobreNomeInf, int ano, int mes, int dia, String telefoneInf, int cpfInf, int anoN, int mesN, int diaN) {

	nome = novoEmpregado;

	sobrenome = sobreNomeInf;

	GregorianCalendar calendario = new GregorianCalendar(ano, mes-1, dia);

	dataAdmissao = calendario.getTime();

	telefone = telefoneInf;

	cpf = cpfInf;

	GregorianCalendar calendarioN = new GregorianCalendar(anoN, mesN-1, diaN);

	nascimento = calendario.getTime();

}



public String getNome(){

	return nome;

}



public String getSobreNome(){

	return sobrenome;

}



public double getSalario(){

	return salario;

}



public Date getDataContratacao(){

	return dataAdmissao;

}



public String getTelefone(){

	return telefone;

}



public Date getDataNascimento(){

	return nascimento;

}



public int getcpf(){

	return cpf;

}



protected void informaSalario(double salarioInformado){

	salario = salarioInformado;

	

}

}[/code]

E como exemplo segue uma classe estendida de Gerente:

[code]public class Gerente extends Empregado {

double comissao;
public static final double salario = 680.60;

public Gerente(String novoEmpregado, String sobreNomeInf, int ano, int mes, int dia, String telefoneInf, int cpfInf, int anoN, int mesN, int diaN) {
	super(novoEmpregado, sobreNomeInf, ano, mes, dia, telefoneInf, cpfInf, anoN, mesN, diaN );
}
public double getComissao(){
	return comissao;
}

public double getSalario(){		
	System.out.println("o salario de " + this.getNome() +
			" é " + super.getSalario());
	
	//double salarioTotal = super.getSalario() + comissao;
	return comissao;
}

}[/code]

[b]
Pessoal, na verdade o que estou querendo fazer, e receber os dados de um novo funcionário, dizer se ele é gerente programador ou secretaria, e como exemplo perguntar se um programador é “sênior”, “júnior” ou “pleno” (a classe programador não foi postada, estou citando apenas um exemplo), e por fim calcular um bônus de cada funcionário em cima do salario!

Ao final do programa, gostaria de mostrar no console uma listagem de todos os programadores, gerentes e secretarias, com seus respectivos dados e salario adicionado com o bônus.

Minhas duvidas são tantas que eu nen sei por onde começar. Mais vamos lá:

  • O código está muito confuso? (o que eu poderia mudar para tornar de mais fácil compreensão);

  • Na linha 64 da classe “ControleFuncionario”, como eu posso fazer para varrer o array e dizer quem e 'gerente", “programador” e “secretaria”, e aplicar alguns métodos?

Galera, por enquanto eu acho que é só. Estou muito confuso, parece que quanto mais eu leio os livros e PDF’s da vida mais “embolada” ficam as minhas idéias!
Ficaria muito agradecido se vocês me ajudassem a desvendar os mistérios da OOP.
Qualquer duvida, se eu tiver me expressado mal estou a plena disposição!

Muito Obrigado

Abrass…[/b]

Olá Manolo,

1º Dica:
Existe algum funcionário de uma empresa que seja do cargo denominado “empregado”? Não, pois “empregado” é um nome genérico para qualquer cargo dentro de uma empresa. Dessa forma, sua classe Empregado nunca será instanciada diretamente, pois não existe ninguém no cargo “empregado”. Seguindo essa idéia, a classe Empregado será alterada para:

public abstract class Empregado{
    //Aqui irá sua implementação
}

2º Dica:
A sua classe Empregado possui no momento 7 atributos (nome, sobrenome, salario, dataAdmissão, telefone, cpf e nascimento). Imagine que tivesse 50!!! Você iria incluir um construtor com 50 (!!!) parâmetros? É claro que não!!!
Dessa forma, classes normalmente possuem os métodos getter e setter.

A sua classe ficará assim:

public abstract class AbstractEmpregado{
    //Aqui constam seus atributos...

    public AbstractEmpregado( ){
        //Aqui você inicializa seus atributos com valores [i]default[/i], normalmente [i]null[/i].
    }

    //Aqui constam seus métodos get e set...

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

3º Dica:
Todas as classes de empregado possuem informações em comum, como:

  • Nome do cargo;
  • Nome do funcionário.

Isso é um indício de que pode ser criada uma interface (não sei se vc já as conhece), a qual teria todos os métodos básicos para um empregado.
Você iria criar a seguinte interface:

public interface EmpregadoInterface{
    public String getNomeCargo();
    public String getNomeEmpregado();
    public String getSobrenomeEmpregado();
    public double getSalarioEmpregado();
    public Date getDataAdmissaoEmpregado();
    public long getCpfEmpregado();
    public Date getDataNascimentoEmpregado();
}

E sua classe abstrata “AbstractEmpregado” mudaria para:

public abstract class AbstractEmpregado implements EmpregadoInterface{
    //Insira aqui seu código...
}

Espero não ter lhe confundido ainda mais, mas com essas alterações e outras que ainda podem ser implementadas, seu código ficará mais claro e próximo ao que o Java propõe, que é trabalhar com objetos.

[b]Hummm…

Muito legal as dicas Eder.
Realmente estava com muitas dúvidas em relação a esse meu construtor “gigantesco”!
Mais não seria muito massivo eu criar métodos getter e setter para todos os atributos? ou seja, não é mais fácil eu inicializá-los todos de uma vez por um construtor?
E como ficaria a linha 61 da classe “ControleFuncionario”, já que vou ter que usar os métodos ao invés do construtor?

Eder, qual a finalidade de “abstract”? E quais serão as mudanças proporcionadas pelo mesmo?

Essa parte de interface prefiro não entrar agora, como você disse minha cabeça já esta uma confusão só!

Muito obrigado pelas dicas Eder!

Forte Abraço.[/b] :slight_smile:

Não se preocupe, aos poucos você vai “pegando” o jeito de se trabalhar com Java.

Pode até ser trabalhoso (depois você verá que usando IDE’s como Eclipse e Netbeans, a geração desses métodos é automática), mas a idéia do Java é que você manipule seus objetos alterando seus atributos. Se tudo for manipulável apenas pelo construtor, não será possível alterar seu objeto após já instanciado.
O objetivo do construtor é inicializar a criação do seu objeto, e não definir todas as suas características (atributos).

E como ficaria a linha 61 da classe "ControleFuncionario", já que vou ter que usar os métodos ao invés do construtor? 

Exemplo:

EmpregadoInterface gerente = new Gerente( );
gerente.setNomeEmpregado( "Fulano" );
gerente.setSobrenamoEmpregado( " da Silva" );

//E assim por diante, para todos os atributos.

Algumas classes NUNCA (pela regra do negócio) devem ser instanciadas (instanciar = new SuaClasse()), pois elas servirão apenas de base para outras que as extenderão. A existência de classes Abstract é muito comum, pois normalmente elas implementam o básico de determinada interface.

As interface são nada mais do que uma definição a ser seguida. Pode ver que no post anterior não implementei a interface, apenas declarei alguns métodos.
Interfaces também são muito utilizadas em Java, e servem para definir algumas características de determinados objetos.

[b]Eder, parece que está clareando minha ideias aqui!

Modifiquei os metodos e retirei o construto (acho que nao vou pecisar por enquanto!), será que estou no caminho certo?[/b]

[code] if (continua==0) {

			Empregado e = new Empregado();
			
			String nome = JOptionPane.showInputDialog(" Informe o nome do novo empregado ");
			e.setNome(nome);
			
			String sobrenome = JOptionPane.showInputDialog(" Informe o seu sobrenome " );
			e.setSobreNome(sobrenome);
			
			String ano = JOptionPane.showInputDialog("Informe o ano de admissao de " + nome);
			int a = Integer.parseInt( ano );   
	        e.setDataAdmissao(a);  
			
			String tel = JOptionPane.showInputDialog("Informe o telefone de " + nome);
			int j = Integer.parseInt(j);
			e.setTelefone(j);
			
			String cpf = JOptionPane.showInputDialog("Informe o cpf de " + nome);
			int c = Integer.parseInt(cpf);
			e.setCpf(c);
		
			
			tipo = JOptionPane.showOptionDialog(null, nome + " e um? ", " Cadastro ", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, tipoFunc, "GERENTE");
			
			if(tipo == 0) {  
				// informou que é GERENTE
				Empregado gerente = new Gerente( );
				empregados[contador] = e.getNome(); e.getSobreNome();// ... Mais o restos dos metodos!
				numGerentes++;
				
				for(int i = 0; i < empregados.length; i++){
					if (empregados[i] instanceof Gerente);
					Gerente p = (Gerente) empregados[i];
				}
				
				p.setNivelPrograma nior";
				psetNome = " jose ";
				
			} else if(tipo == 1) {
				// informou que é SECRETARIA
				empregados[contador] = new Secretaria(nome, sobrenome, a, m, d, tel, c, aN, mN, dN);
				numSecret++;
				
			} else {
				// informou que é PROGRAMADOR
				empregados[contador] = new Gerente(nome, sobrenome, a, m, d, tel, c, aN, mN, dN);
				numProgram++;
			}
			
			contador++;	// incrementa o numero de funcionarios cadastrados
		}
		
	} while (continua == 0);

	System.out.println("LISTANDO NA CONSOLE OS REGISTROS DO VETOR DE FUNCIONARIOS.... ");
	
	for (int i = 0; i < contador; i++) {
		System.out.println("EMPREGADO NO REGISTRO ["+i+"] = " + empregados[i].getNome()+ empregados[i].getSobreNome());
	}
	
}

}[/code]
[b]
Obrigado cara!

Abraço[/b] :smiley:

Ao invés disso:

Empregado[] empregados = new Empregado[100];

Tente isso:

List< Empregado > empregados = new ArrayList< Empregado >();

Para incluir um novo empregado:

empregados.add( empregado );    //Onde "empregado" é uma instância de Empregado

Para obter um empregado:

Empregado empregado = empregados.get( index );    //Onde "index" é a posição de armazenamento dentro da lista (index = 0: primeira posição)

Dessa forma, ao invés de:

for (int i = 0; i < contador; i++) {  
    System.out.println("EMPREGADO NO REGISTRO ["+i+"] = " + empregados[i].getNome()+ empregados[i].getSobreNome());  
}  

Você pode usar:

for( Empregado empregado : empregados ){
    System.out.println( "Nome do Empregado: " + empregado.getNome() + empregado.getSobreNome() );
}

[b]Então Eder, o problema que o professor especificou para ser usado o array desta forma que etá em meu código, e também os princípios de herança!

Porque está dando erro:[/b]

Empregado gerente = new Gerente( ); empregados[contador] = e.getNome();// cannot convert String to Empregado

Está minha ideia de fazer os questionamentos sobre o funcionário, e logo em seguida setar eles no método está certa?
E como posso pegar esses dados que eu setei do objeto “e” e passar para o array? Ou apenas objetos podem ser passados para o array!
Como pode ver no código acima gostaria de passar o objeto “e” para o array de empregados com todos os métodos setados, mas ocorre um erro como descrito no comentário.

Você só pode atribuir a uma variável objetos que sejam instância do seu tipo. No teu caso, você está tentando armazenar na variável “empregados” (que é um array do tipo Empregado) um objeto que é uma instância de String.

Pode fazer assim:

Empregado gerente = new Gerente( );  
empregados[ contador ] =  gerente;    //Onde "gerente" é uma instância de Empregado.

[b]Nossss, ta muito complicado! To no desespero :evil:

Bom, não sei se entendi direito o que você quis dizer Eder. Mais que dizer que “empregados[]” só aceita objetos de “Empregado”?

E finalmente a dúvida mortal (proporcional ao meu desespero). Se eu estou atribuindo “gerente” à posição 0 de “empregados[]”, como posso armazenar as informações que eu setei no começo no objeto “e” nessa posiçao de “empregados[]”?

Espero ter sido claro!

Abraço…[/b]

No seu caso, você criou dois objetos: um primeiro (empregado) que armazena os dados gerais do empregado; e um segundo (gerente), que você cria quando o usuário especifica o tipo de empregado. Dessa forma, você tem que “transportar” as informações de “empregado” para “gerente”. O melhor seria criar o objeto “gerente” já no início, antes de coletar as informações. Dessa forma, todas as informações já estarão no objeto que será armazenado no array “empregados”.

Ficaria mais ou menos assim (pode haver alguns erros de sintaxe):

if( continua==0 ){
                 Empregado e = null;
                   
                 tipo = JOptionPane.showOptionDialog(null, "Cargo do Empregado? ", " Cadastro ", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, tipoFunc, "GERENTE");  
                   
                 if(tipo == 0) {    
                     // informou que é GERENTE  
                     e = new Gerente( );  
                     empregados[ contador ] = e;
                     numGerentes++;  
                       
                     for(int i = 0; i < empregados.length; i++){  
                         if (empregados[i] instanceof Gerente);  
                         Gerente p = (Gerente) empregados[i];  
                     }  
                       
                     p.setNivelPrograma nior";  
                     psetNome = " jose ";  
                       
                 }
                 else {
                     if(tipo == 1) {  
                     // informou que é SECRETARIA  
                     e = new Secretaria( );  
                     empregados[contador] = e;  
                     numSecret++;  
                       
                 } else {  
                     // informou que é PROGRAMADOR  
                     e = new Programador( );  
                     empregados[contador] = e;
                     numProgram++;  
                 }  
                   
                 String nome = JOptionPane.showInputDialog(" Informe o nome do novo empregado ");  
                 e.setNome(nome);  
                   
                 String sobrenome = JOptionPane.showInputDialog(" Informe o seu sobrenome " );  
                 e.setSobreNome(sobrenome);  
                   
                 String ano = JOptionPane.showInputDialog("Informe o ano de admissao de " + nome);  
                 int a = Integer.parseInt( ano );     
                 e.setDataAdmissao(a);    
                   
                 String tel = JOptionPane.showInputDialog("Informe o telefone de " + nome);  
                 int j = Integer.parseInt(j);  
                 e.setTelefone(j);  
                   
                 String cpf = JOptionPane.showInputDialog("Informe o cpf de " + nome);  
                 int c = Integer.parseInt(cpf);  
                 e.setCpf(c);  
                   
                 contador++; // incrementa o numero de funcionarios cadastrados  
             }  
               
         } while (continua == 0);  
   
         System.out.println("LISTANDO NA CONSOLE OS REGISTROS DO VETOR DE FUNCIONARIOS.... ");  
           
         for (int i = 0; i < contador; i++) {  
             System.out.println("EMPREGADO NO REGISTRO ["+i+"] = " + empregados[i].getNome()+ empregados[i].getSobreNome());  
         }  
           
     }  
       
       
       
 }

Olá

Manolo, por favor não escreva tudo em negrito pois fica muito difícil de ler. Eu não consegui.

Obrigado

[]s
Luca

Mil desculpas Luca!
Eu realmente não sabia sobre a formatação do texto.

Você quer que eu poste alguma parte do código em especial?

Obrigado pela dica, e desculpas!

Abraço…

Galera estou com dúvida no meu método de setar a data de admissao de um gerente!

classe “ControleFuncionaro”:

[code] String ano = JOptionPane.showInputDialog("Informe o ano de adimissao " + gerente.getNome());
int a = Integer.parseInt(ano);

 String mes = JOptionPane.showInputDialog("Informe o mes de adimissao " + gerente.getNome());
 int  m = Integer.parseInt(mes);
			    
 String dia = JOptionPane.showInputDialog("Informe o dia de adimissao " + gerente.getNome());
 int  d = Integer.parseInt(dia);
			    
  gerente.setDataAdmissao(a, m, d);[/code]

Classe “Empregado”:

public void setDataAdmissao(Date ano, mes, dia) { GregorianCalendar calendario = new GregorianCalendar(ano, mes-1, dia); dataAdmissao = calendario.getTime();

O erro que esta ocorrendo na classe “ControleFuncionario”:

The method setDataAdmissao(Date) in the type Empregado is not applicable for the arguments (int, int, int)

E finalmente o erro na classe “Empregado”:

Multiple markers at this line - Syntax error on token ",", delete this token - Method breakpoint:Empregado [entry] - setDataAdmissao (Date) - mes cannot be resolved to a type

Já dei uma lida na api, mas não sei poque esta ocorrendo o erro na classe “Empregado”

public void setDataAdmissao( int ano, int mes, int dia );

Muito obrigado pela a ajuda Eder. :smiley: