[resolvido] Ajuda com com terminal bancário, problema com array. Como resolver?

Olá pessoal, esse é meu primeiro tópico na comunidade, então peço desculpas se assim o fiz em local errado ou de maneira incorreta.

Vamos ao meu problema:

Meu professor da faculdade que nos ensina Java orientado a Objetos, ele nos passou uma tarefa com várias classes [modelos de objetos], que precisam ser chamados e iniciados todos na classe principal.

Vide abaixo os códigos fonte das classes:

Conta.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package poo.gestaodecontas;

/**
 *
 * @author Ronilson Alves
 */
public class Conta {
    
    private int numero;
    private int senha;
    private double saldo;
    private Lancamentos[] lancamentos;
    private int ultimoLancamento;
    
    public Conta (int numero, int senha, double saldo) {
        this.numero = numero;
        this.senha = senha;
        this.saldo = saldo;
        this.lancamentos = new Lancamentos[11];
    }
    
    public int getNumero() {
        return this.numero;
    }
    
    public double getSaldo() {
        return this.saldo;
    }
    
    public double verificaSaldo(int senha) {
        if(this.senha != senha) {
            return -1;
        } else {
            return this.saldo;
        }
    }
    
    public boolean debitaValor(int senha, double valor, String operacao) {
        if(valor < 0 | this.senha != senha | this.saldo < valor) {
            return false;
        }
        if(this.ultimoLancamento == 10) {
            for (int i = 0; i < 10; i++){
                this.lancamentos[i] = this.lancamentos[i+1];
            }
        } else {
            this.ultimoLancamento++;
        }

        this.saldo -= valor;
        return true;
    }
    
    public boolean creditaValor(double valor, String operacao){
        if(valor < 0) {
            return false;
        }
        if (this.ultimoLancamento == 10) {
            for (int i = 0; i < 10; i++){
                this.lancamentos[i] = this.lancamentos[i+1];
            }
        } else {
            this.ultimoLancamento++;
        }
        this.saldo += valor;
        return true;
    }
    
    public boolean transfereOutraConta(double valor, String operacao) {
        if (valor < 0 | valor > this.getSaldo()) {
            return false;
        }
        if (this.ultimoLancamento == 10) {
            for (int i = 0; i < 10; i++){
                this.lancamentos[i] = this.lancamentos[i+1];
            } 
        } else {
            this.ultimoLancamento++;
        }
        this.saldo -= valor;
        return true;
    }
    
    public boolean exibeExtrato(int senha) {
        if (this.senha != senha | this.lancamentos == null) {
            return false;
        }
        for (int i = 1; i < lancamentos.length; i++) {
            System.out.println(this.lancamentos[i].toString());
        }
        return true;
    }
    

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

CadastroContas.java

import poo.gestaodecontas.Conta;

/**
 *
 * @author Ronilson Alves
 */
public class CadastroContas {
    
    private Conta contas[];
    private int numeroDeContas;
    
    public CadastroContas(int numeroDeContas) {
        this.contas = new Conta[numeroDeContas + 1];
    }
    
    public boolean insereConta(Conta conta) {
        if (this.numeroDeContas >= this.contas.length) {
            return false;
        } else {
            for (int i = 1; i <= this.numeroDeContas; i++) {
                if (conta.getNumero() == this.contas[i].getNumero()){
                    return false;
                }
            }
            this.numeroDeContas++;
            this.contas[numeroDeContas] = conta;
            return true;
        }
    }
    
    public Conta buscaConta(int numeroConta) {
        for (int i = 1; i <= this.numeroDeContas; i++) {
        if (numeroConta == this.contas[i].getNumero()) {
            return this.contas[i];
        }
    }
        return null;
    }
}

Lancamentos.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package poo.gestaodecontas;

/**
 *
 * @author Ronilson Alves
 */
public class Lancamentos {
    
    private String operacao;
    private double valor;
    
    public Lancamentos(String operacao, double valor) {
        this.operacao = operacao;
        this.valor = valor;
    }
    
    public String getOperacao() {
        return operacao;
    }
    
    public double getValor() {
        return valor;
    }

    public String toString() {
        return "Operação: "+this.getOperacao()+
               "\tValor: " + this.getValor();
    }
    
}

Caixa.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package poo.gestaodecaixaeletronico;

import poo.dados.CadastroContas;
import poo.gestaodecontas.Conta;

/**
 *
 * @author Ronilson Alves
 */
public class Caixa {
    
    private Terminal meuCaixaEletronico;
    private CadastroContas bdContas;
    private double saldoCaixa;
    
    public Caixa (Terminal terminal, CadastroContas bd) {
        this.meuCaixaEletronico = terminal;
        this.bdContas = bd;
    }
    
    public double consultaSaldo(int numeroDaConta, int senha) {
        Conta conta;
        conta = this.bdContas.buscaConta(numeroDaConta);
        if (conta != null) {
            return conta.verificaSaldo(senha);
        } else {
            return -1;
        }
    }
    
    public boolean efetuaSaque(int numeroDaConta, double valor, int senha){
        if (valor < 0 || (valor%50) != 0 || valor > 500 || valor > this.saldoCaixa) {
            return false;
        }
        
        Conta conta = bdContas.buscaConta(numeroDaConta);
        
        if (conta == null || !conta.debitaValor(senha, valor, "Saque Automatico")){
            return false;
        }
        
        this.liberaNotas((int)(valor/50));
        this.saldoCaixa -= valor;
        
        if (this.saldoCaixa < 500){
            this.meuCaixaEletronico.setModo(0);
        }
        return true;
    }
    
    public boolean efetuaDepositoDinheiro(int numeroDaConta, double valor) {
        Conta conta = bdContas.buscaConta(numeroDaConta);
        if (valor < 0 | conta == null) {
            return false;
        }
        conta.creditaValor(valor, "Deposito em especie");
        this.saldoCaixa += valor; // o dinheiro depositado em dinheiro ficará
                                  // disponível no saldo do caixa eletrônico.
        return true;
    }
    
    public boolean efetuaDepositoCheque(int numeroDaConta, double valor) {
        Conta conta = bdContas.buscaConta(numeroDaConta);
        if (valor < 0 | conta == null) {
           return false;
        }
        conta.creditaValor(valor, "Deposito em cheque");
        return true;
    } 
    
    public boolean efetuaTransferencia(int numeroContaOrigem, double valor, int senha, int numeroContaDestino) {
        Conta cOrigem = bdContas.buscaConta(numeroContaOrigem);
        Conta cDestino = bdContas.buscaConta(numeroContaDestino);
        if (cOrigem == null || cDestino == null || valor < 0 || !cOrigem.debitaValor(senha, valor, "Transferencia enviada")) {
            return false;
        }
        cDestino.creditaValor(valor, "Transferencia recebida");
        //cDestino.setSaldo(valor);
        return true;
    }
    
    //funcao para exibir extrato, verificar formas de melhora-la depois
    public boolean mostraExtrato(int numeroDaConta, int senha){
        Conta conta = bdContas.buscaConta(numeroDaConta);
        if (!conta.exibeExtrato(senha) || conta == null) {
            return false;
        }
        conta.exibeExtrato(senha);
        return true;
    }
    public void recarrega(){
        this.saldoCaixa += 1000; // aqui fiz uma pequena alteração 
                                 // para o saldo do caixa ser somado ao valor
                                 // recarregado. No seu código ele seta
                                 // independente do valor que tenha sobrado no
                                 // ATM para R$ 1000. aqui esse saldo é somado.
        System.out.println("Saldo atual do caixa: " + this.saldoCaixa);
        this.meuCaixaEletronico.setModo(1);
    }
    
    private void liberaNotas(int quantidade) {
        while(quantidade-- > 0) {
            System.out.println("===/ R$50,00 /===");
        }
    }
        
}

Terminal.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package poo.gestaodecaixaeletronico;

import java.util.Scanner;
import poo.dados.CadastroContas;

/**
 *
 * @author rooni
 */
public class Terminal {
    
    private Caixa meuCaixa;
    private int modoAtual;
    
    public Terminal(CadastroContas bd) {
        this.meuCaixa = new Caixa(this, bd);
    }
    
    public void iniciaOperacao() {
        int opcao;
        opcao = this.getOpcao();
        
        while (opcao != 0) {
            switch (opcao) {
                case 1:
                    boolean depDinheiro = this.meuCaixa.efetuaDepositoDinheiro(getInt("Número da conta"),getInt("Valor"));
                    if (depDinheiro) {
                        System.out.println("Deposito em dinheiro efetuado com sucesso!");
                    } else {
                        System.out.println("Pedido de deposito em dinheiro recusado");
                    }
                    break;
                case 2:
                    boolean depCheque = this.meuCaixa.efetuaDepositoCheque(getInt("Numero da conta"),getInt("Valor"));
                    if (depCheque) {
                        System.out.println("Deposito em cheque efetuado com sucesso!");
                    } else {
                        System.out.println("Pedido de deposito em cheque recusado");
                    }
                    break;
                case 3:
                    double saldo = this.meuCaixa.consultaSaldo(getInt("Numero da conta"),getInt("Senha"));
                    if (saldo != -1){
                        System.out.println("Saldo Atual: " + saldo);
                    } else {
                        System.out.println("Conta ou senha inválida");
                    }
                    break;

                case 4:
                    boolean b = this.meuCaixa.efetuaSaque(getInt("Numero da conta"), (double) getInt("Valor"), getInt("Senha"));
                    if (b) {
                        System.out.println("Retire o dinheiro");
                    } else {
                        System.out.println("Pedido de saque recusado");
                    }
                    break;
           
                case 5:
                    boolean tContas = this.meuCaixa.efetuaTransferencia(getInt("Conta de origem"), (double) getInt("Valor"), getInt("Senha"), getInt("Conta de destino"));
                    if (tContas) {
                        System.out.println("Transferencia efetuada com sucesso!");
                    } else {
                        System.out.println("Ocorreu um erro com a sua transação");
                    }
                    break;
                    
                case 6: // chama exibir Extrato
                    boolean mExtrato = this.meuCaixa.mostraExtrato(getInt("Numero da conta"),getInt("Senha"));
                    if(mExtrato) {
                        System.out.println("Extrato sujeito a alteração!");
                    } else {
                        System.out.println("Ocorreu um erro ao exibir seu extrato");
                    }
                    break;
                
                case 7:
                    this.meuCaixa.recarrega();
                    break;
            }
            opcao = getOpcao();
        }
    }
    
    public void setModo(int modo) {
        if (modo == 0 || modo == 1){
            this.modoAtual = modo;
        }
    }
    
    private int getOpcao() {
        int opcao;
        do {
            if (this.modoAtual == 1){
                opcao = getInt("Opcao: 1 - Depositar (em dinheiro), 2 - Depositar (em cheque), "
                        + "3 - Consultar Saldo, 4 - Realizar Saque, 5 - Transferir, 6 - Exibir Extrato, 0 - Sair");
                if (opcao !=0 & opcao != 1 & opcao != 2 & opcao != 3 & opcao != 4 & opcao != 5 & opcao != 6){
                    opcao = 77;
                }
            } else {
                opcao = getInt("Opcao: 7 - Recarregar, 0 - Sair");
                if (opcao != 7 & opcao != 0) {
                    opcao = 77;
                }
            }
        } while (opcao == 77);
        return opcao;
    }
    
    private int getInt(String string) {
        
        Scanner r = new Scanner (System.in);
        System.out.println("Entre com "+string);
        
        if (r.hasNextInt()){
            return r.nextInt();
        }
        
        String st = r.next();
        System.out.println("Erro na Leitura dos Dados");
        return 0;
    }
}

TestaCaixaEletronico.java (seria a classe principal)

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package poo.gestaodecaixaeletronico;

import poo.dados.CadastroContas;
import poo.gestaodecontas.Conta;
import poo.gestaodecontas.Lancamentos;

/**
 *
 * @author Ronilson Alves
 */
public class TestaCaixaEletronico {
    public static void main(String[] args){
        Conta c1, c2, c3, c4, c5, c6, c7, c8, c9, c10;
        c1 = new Conta(1234,1234,200);
        c2 = new Conta(2345,1234,300);
        c3 = new Conta(3456,1234,200);
        c4 = new Conta(4567,1234,250);
        c5 = new Conta(5678,1234,700);
        c6 = new Conta(6789,1234,650);
        c7 = new Conta(7890,1234,750);
        c8 = new Conta(8901,1234,400);
        c9 = new Conta(9012,1234,500);
        c10 = new Conta(1123,1234,740);
        
        // aqui eu precisaria criar e instanciar um objeto Caixa e um outro
        // Terminal para poder jogar essas contas no CadastroContas.java
        // e poder iniciar a operação do caixa eletrônico.
        // o que eu não estou conseguindo fazer.
        CadastroContas bdContas = new CadastroContas(10);
        Terminal meuTerminal = new Terminal(bdContas);
        
        bdContas.insereConta(c1);
        bdContas.insereConta(c2);
        bdContas.insereConta(c3);
        bdContas.insereConta(c4);
        bdContas.insereConta(c5);
        bdContas.insereConta(c6);
        bdContas.insereConta(c7);
        bdContas.insereConta(c8);
        bdContas.insereConta(c9);
        bdContas.insereConta(c10);
        
        
        meuTerminal.iniciaOperacao();
    }
}

Preciso exibir o extrato das movimentações das contas para o usuário, mas estou recebendo uma exception de estou dos vetores, poderiam me ajudar e me dizer o que estou fazendo de errado?

Exception in thread "main" java.lang.NullPointerException
	at poo.gestaodecontas.Conta.exibeExtrato(Conta.java:94)
	at poo.gestaodecaixaeletronico.Caixa.mostraExtrato(Caixa.java:90)
	at poo.gestaodecaixaeletronico.Terminal.iniciaOperacao(Terminal.java:74)
	at poo.gestaodecaixaeletronico.TestaCaixaEletronico.main(TestaCaixaEletronico.java:49)

Vc está chamando toString de algo null. Não há um objeto Lancamento nesta posição.

1 curtida
        if (this.ultimoLancamento == 10) {
            for (int i = 0; i < 10; i++){
                this.lancamentos[i] = this.lancamentos[i+1];
            } 
        } else {
            this.ultimoLancamento++;
            // teria que setar os valores de Lancamento aqui, por exemplo.
        }
        this.saldo -= valor;
        return true;

Então, se entendi, embora tenha iniciado o objeto lançamentos dentro da classe conta, ainda assim não criei nenhum objeto do tipo Lançamento, é isso? Teria como fazer isso em cada método da classe conta, debita, credita, transfere, etc. Como faço isso?

para inicialização uma posição você teria algo como:

this.lancamento[i] = new Lancamento(operacao, valor);

Você é obrigado a utilizar array como estrutura? você já tentou utilizar ArrayList por exemplo?

No seu caso usar um ArrayList ou um Stack seria melhor opção, pois você não ficaria preso ao tamanho do array pré definido, evitaria acessar objetos null do array e não precisaria percorrer todas as posições a todo momento.

1 curtida

Obrigado pela ajuda Danielzilli, mas toda vez que crio um objeto conta, ele já instancia um objeto array lancamentos setado com null em todas as 11 posições.

    public Conta (int numero, int senha, double saldo) {
        this.numero = numero;
        this.senha = senha;
        this.saldo = saldo;
        this.lancamentos = new Lancamentos[11];
    }

O professor quer que utilizemos o array para armazenar até 10 transações da conta (saque, deposito, transferência, etc).
Por exemplo, um objeto conta c1 que tem seus atributos inicializados num construtor, com exceção do ultimoLancamento, que por padrão é setado para 0 vai ter a seguinte estrutura (conforme imagem descritiva)
map
Na representação do vetor/atributo lacamentos[11] eu, toda vez que uma conta c1 realizar uma operação, vai ter que ficar registrada dentro desse vetor com a descrição ‘operacao’ e o ‘valor’ até o limite de 10, se ultrapassar esse limite, todos os itens do vetores terão que ser deslocados à esquerda, só vou exibir os itens de 1 ao 10, sendo que a posição 10 sempre vai ser a mais recente. Minha dúvida era, como eu vou ter que passar essas informações para dentro desse objeto em toda vez que houver uma transação na conta c1? R= utilizando ultimoLancamento como índice do meu vetor lancamentos.

Aqui por exemplo, no método debita valor esse registro se faz necessário:

    public boolean debitaValor(int senha, double valor, String operacao) {
        if(valor < 0 | this.senha != senha | this.saldo < valor) {
            return false;
        }
        if(this.ultimoLancamento == 10) {
            for (int i = 0; i < 10; i++){
                this.lancamentos[i] = this.lancamentos[i+1];
            }
           this.lancamentos[ultimoLancamento] = new Lancamentos(operacao,valor);
        } else {
            this.ultimoLancamento++;
            this.lancamentos[ultimoLancamento] = new Lancamentos(operacao,valor);
// aqui acredito que além de atualizar a
// a quantidade de transações efetuadas, deveria fazer a atribuição ao meu vetor
// lancamentos[]
// this.lacamentos[i] = new Lacamentos (operacao, valor);
        }

Danielzilli, depois de sua ajuda, consegui realizar a tarefa, grato!