"Estouro" da pilha!

Olá, estou com um problema que literalmente está fritando meus “miolos”, segue ele abaixo;

	public static void main(String args[]){
		
	    Cliente linkCliente = new Cliente();
			
		Cliente c1 = new Cliente();
		c1.numero =  "115.251";
		c1.nome = "Robison";
		c1.sobreNome = "Aleixo";
		c1.cpf = "254.845.874-1";
		linkCliente.adicionar(c1);
	    c1.mostraCliente ();
	    
	    Cliente c2 = new Cliente();
		c2.numero =  "115.252";
		c2.nome = "João";
		c2.sobreNome = "da Silva e Silva";
		c2.cpf = "854.777.654-9";
		linkCliente.adicionar(c1);
	    c2.mostraCliente ();
			
		//c1.linkConta.deposita (1500);
		//c1.transferePara (c2, 100);	
			 

	}
}
class Cliente {
	
     Conta linkConta = new Conta();  	 	
	 String numero;
	 String nome;
	 String sobreNome;
	 String cpf;
	 Cliente[] clienteadd = new Cliente[10];
   	 int cont;
			
	void adicionar (Cliente c){
		if (cont < clienteadd.length) {
			clienteadd[cont] = c;
			cont++;		
		}
		else {
			System.out.println ("Está cheio!!!");
		}
	}

	public void mostraCliente () {
		 System.out.println ("Número da conta: " + numero);    
		 System.out.println ("Nome do titular: " + nome + " " + sobreNome + 
		 						" - CPF:" + cpf + "\n");
	}			  	   
} 
class Conta {
	private double saldo;
	private double limite = 500;
	Cliente clienteLink = new Cliente();
	Funcionario funcionario = new Funcionario();  
	
	
    public boolean saca (double valor) {
		if (valor > this.saldo + this.limite) {   // saca o saldo atual + o limite
			return false; //não vai sacar, está sacando mais do que o valor atual			
		}
		else {
			this.saldo = this.saldo - valor;
			return true;
		}		
	}
	
	public void deposita (double quantidade) {
		this.saldo += quantidade;		
	} 
	
	public boolean transferePara (Conta destino, double valor) { //Conta cria uma variável temporaria chamada destino
		boolean retirou = this.saca (valor);
		if (retirou == false) {
			System.out.println ("Sr(a) " + clienteLink.nome + ", sua operação não foi realizada, seu saldo atual é de: " + saldo);
			System.out.println ("Valor da operaçõa: " + valor + "\n") ;
			return false;
		}
		else {
			destino.deposita (valor);
			System.out.println ("Sucesso");			
			return true;
		}
	}
	
	
	public void mostra () {
		 System.out.println (saldo);
	} 			   
}

Quando acrescento a seguinte linha:
Cliente linkCliente = new Cliente();

No objeto Cliente acontece o seguinte erro:

“Exception in thread “main” java.lang.StackOverflowError”

Pelo que andei lendo se trata de um “estouro” da pilha, mais não consegui localizar onde está ocorrendo isso.

Preciso que o obejeto Cliente tenha acesso ao objeto Conta. Para poder executar o método deposita entre outro que se encontrão no objeto Conta.
Alguém sabe se fiz alguma coisa errada?

Desde já agradeço!
Abraço

Cada cliente que você instancia, automaticamente instancia 10 clientes. Quem criam cada um 10 clientes… e que criam 10 clientes… até estourar a pilha.

Cliente[] clienteadd = new Cliente[10];  

Como eu posso consertar isso?

Quando eu trabalho com 2 objetos trocando dados não tenho esse problema, mais agora que eu quiz “enfeitar” deu nisso.

Abraço

O problema não é esse. O problema é que um cliente cria uma conta, e uma conta cria um cliente, que por sua vez criará uma conta, que por sua vez criará um cliente… e por aí vai…

Para resolver o problema… crie a Conta separadamente, e associe-a a um cliente:

[code]class Cliente {
Conta linkConta; //Não dê new aqui! Obteremos essa conta de fora!
String nome;
String sobreNome;
String cpf;
int cont;

//Crie um construtor que recebe a conta.
public Cliente(Conta conta) {
this.conta = conta;
}

public void mostraCliente () {
System.out.println ("Número da conta: " + numero);
System.out.println (“Nome do titular: " + nome + " " + sobreNome +
" - CPF:” + cpf + “\n”);
}
} [/code]

[code]class Conta {
private double saldo;
private double limite = 500;
String numero;

public boolean saca (double valor) {  
    if (valor > this.saldo + this.limite) {   // saca o saldo atual + o limite  
        return false; //não vai sacar, está sacando mais do que o valor atual             
    }  
    else {  
        this.saldo = this.saldo - valor;  
        return true;  
    }         
}  

public void deposita (double quantidade) {  
    this.saldo += quantidade;         
}   

public boolean transferePara (Conta destino, double valor) { //Conta cria uma variável temporaria chamada destino  
    boolean retirou = this.saca (valor);  
    if (retirou == false) {  
        System.out.println ("Sua operação não foi realizada, seu saldo atual é de: " + saldo);  
        System.out.println ("Valor da operaçõa: " + valor + "\n") ;  
        return false;  
    } else {  
        destino.deposita (valor);  
        System.out.println ("Sucesso");           
        return true;  
    }  
}  

public void mostra () {  
    System.out.println (saldo);  
}                

}
[/code]

E, na hora de criar:

Conta conta = new Conta(); Cliente cli = new Cliente(conta);

Detalhe… o número é da conta ou do cliente? É da conta, concorda? Então, o que ele estava fazendo na classe do Cliente?

Verdade é que fucei tanto pra tentar arrumar aqui que bagunço tudo.

Cara funciono certinho agora, vou criar outros exemplos aqui pra praticar esse método.
Obrigado Brother, pode sacar uns 2.000 ai. hahhaha :lol:

Abraço

Opa, dei uma reformulada geral no código:

[code]class Programa {
public static void main(String args[]){

/------------NOVO-CLIENTE----------------/

	Cliente cliente1 = new Cliente();
	Conta conta1 = new Conta(cliente1);
	 
	cliente1.setNome("Robison");
	cliente1.setSobreNome("Aleixo");
	cliente1.setCpf("254.845.874-1"); 
	cliente1.getMostraCliente();
	cliente1.setAdicionar(cliente1);
	
    conta1.setDeposita(200);
    System.out.println("Saldo atual:" + conta1.getSaldo() + "\n");	

/------------NOVO-CLIENTE----------------/

    Cliente cliente2 = new Cliente();
    Conta conta2 = new Conta(cliente2);
    
    cliente2.setNome("João");
    cliente2.setSobreNome("da silva");
    cliente2.setCpf("458.72.887-7");
    cliente2.getMostraCliente();
    cliente2.setAdicionar(cliente2);
    
    conta2.setNumero("254.545.25");
//  conta2.setTransferePara(conta1,000);
    conta2.setDeposita(200);
    	    
	System.out.println("Número da conta: " + conta2.getNumeto());
    System.out.println("Saldo atual: " + conta2.getSaldo() + "\n");    
}

}
[/code]

[code]class Cliente {

 private String nome;
 private String sobreNome;
 private String cpf;
 private int cont;
 Cliente[] clienteadd = new Cliente[10]; 
 
 public void setNome(String nome) {
 this.nome = nome;
 }
    	  
 public void setSobreNome(String sobreNome) {
 	this.sobreNome = sobreNome;
 }
  
 public void setCpf(String cpf) {
 	this.cpf = cpf;
 } 
 	 	 			
 public void setAdicionar (Cliente c){
	if (cont < clienteadd.length) {
		clienteadd[cont] = c;
		cont++;		
	}
	else {
		System.out.println ("Está cheio!!!");
	}
}
	
public void getMostraCliente () {
	 System.out.println ("Nome do titular: " + nome + " " + sobreNome + " - CPF:" + cpf);
}			  	   

}
[/code]

[code]class Conta {
private static int totalDeContas;
private double saldo;
private double limite = 100;
private String numero;
private Cliente titular;

public void setNumero(String numero) {
	this.numero = numero;
}

public String getNumeto() {
	return this.numero;
}	
	
public boolean setSaca (double valor) {
	if (valor > this.saldo + this.limite) { 
		return false; 	
	}
	else {
		this.saldo = this.saldo - valor;
		return true;
	}		
}

public void setDeposita (double quantidade) {
	if (quantidade > 0) {
		this.saldo += quantidade;
	//	System.out.println ("Deposito efetuado com sucesso!");	
			
	}
	else {
		System.out.println("Operação não realizada, tente outro valor!");
	}	
} 

public boolean setTransferePara (Conta destino, double valor) { 
	boolean retirou = this.setSaca (valor);
	if (retirou == false) {
	//	System.out.println ("Sr(a) " + clienteLink.nome + ", sua operação não foi realizada, seu saldo atual é de: " + saldo);
	//	System.out.println ("Valor da operaçõa: " + valor + "\n") ;
		return false;
	}
	else {
		destino.setDeposita (valor);
	//	System.out.println ("Transferencia efetuada com sucesso!");			
		return true;
	}
}
	
public double getSaldo() {
	return this.saldo + this.limite;
} 	
	
public static int getTotalDeContas() {
	return Conta.totalDeContas;
}		

Conta(Cliente titular) {
	 Conta.totalDeContas = Conta.totalDeContas +1;	
	 this.titular = titular;	
	}	   

}
[/code]

Tenho que relacionar a conta criada na classe cliente com outras insformações na classe conta, ou seja preciso unir essas 2 informações em 1 só e adicionar essa conta em um array (Cliente[] clienteadd = new Cliente[10]; ).
Gostaria de saber se esse é o método correto de fazer isso. Pelos testes que realizei está certo.

Abraço

Sim. Você tem duas possibilidades. Definir um titular na conta, o que você fez.

Ou criar uma Lista de contas na classe Cliente. Acho que para seu trabalho, essa está mais do que boa.

Ainda não entendi uma coisa.

Por que seu cliente tem um array de clientes dentro?

Um cliente possui 10 clientes?

Se você quer ter uma coleção de clientes, ela deve ficar fora da sua classe cliente.

[quote=pablosaraiva]Ainda não entendi uma coisa.

Por que seu cliente tem um array de clientes dentro?

Um cliente possui 10 clientes?

Se você quer ter uma coleção de clientes, ela deve ficar fora da sua classe cliente.[/quote]

Exato. Nesse caso, uma classe Agencia poderia ter o array de clientes.

hahaha. Estou ficando com vergonha já. :oops: Pessoal seu estiver enchendo muito o “saco” pode falar.

Mais seria algo assim:

[code]class Agencia {
private int cont;
Agencia[] clienteadd = new Agencia[10];

	public void setAdicionar (Agencia c){
	if (cont < clienteadd.length) {
		clienteadd[cont] = c;
		cont++;		
	}
	else {
		System.out.println ("Está cheio!!!");
	}
}

}[/code]

Criei esse construtor na classe Programa

  Agencia adicionar;
        //.....
		Programa(Agencia adicionar){
		       this.adicionar = adicionar;
		}

Para adicionar esse os dados digitados na class Cliente e Conta, seria algo do tipo:

Agencia pessoa1 = new Agencia(conta1);
pessoa1.setAdicionar(conta1);

Pelos meus testes aqui fail, mais estou no caminho certo?
Eu vo aprender essa porcaria de array nem que eu tenha que fazer um curso só pra isso.

Abraço

Eu falei na agência ter um array de clientes, não um array de agências… :lol:

Relaxa cara, estamos aqui pra ajudar. :slight_smile:

Acho que agora foi. :roll:

class Agencia {
	private int cont;
	private Conta conta;	
	Cliente[] clienteadd = new Cliente[10];
	
	public void setAdicionar (Cliente c){ 
		if (cont < clienteadd.length) {
			clienteadd[cont] = c;
			cont++;		
		}
		else {
			System.out.println ("Está cheio!!!");
		}
	}
	
	Agencia (Conta conta) {
		this.conta = conta;
	}
	
}
	    Cliente cliente2 = new Cliente();
	    Conta conta2 = new Conta(cliente2);
	    Agencia agencia2 = new Agencia(conta2);
	    
	    cliente2.setNome("João");
	    cliente2.setSobreNome("da silva");
	    cliente2.setCpf("458.72.887-7");
	   	agencia2.setAdicionar(cliente2);

Só tem um problema, quando peço para mostrar a array da nisso:

Mostrar toda array: Cliente@9304b1
Mostrar toda array: null
Mostrar toda array: null
Mostrar toda array: null
Mostrar toda array: null
Mostrar toda array: null
Mostrar toda array: null
Mostrar toda array: null
Mostrar toda array: null
Mostrar toda array: null

É que vc não pode simplesmente mandar imprimir um array, ou um Cliente. Você tem que percorrer o array, e imprimir um por um:

for (Cliente cli : clientes) { System.out.println("Cliente: " + cli.nome); }

Para que uma classe se torne imprimível, você precisa adicionar a ela o método toString(). Ele que é chamado quando tenta-se imprimir diretamente um objeto. Por exemplo, adicione o seguinte método toString na sua classe de clientes:

@Override public String toString() { return "Nome: " + nome; }

E poderá fazer direto:

System.out.println(cliente);