Orientação a Objeto - Tratamento de Erros Usando Exceções

Objetivos da Seção

O Problema: Como Tratar Erros

/*
 * Leitura em laço, com tratamento de erro
 */

import p1.aplic.cartas.*;
import p1.io.*;

public class Cartas7 {
  public static void main(String[] args) {
    int     rodadas = 0;
    String  resposta;
    boolean respostaOK = false;

    while(!respostaOK) {
      resposta = Entrada.in.lerLinha("Quantas rodadas quer jogar?");
      if(resposta == null) {
        // fim de entrada
        System.exit(0);
      }
      rodadas = Integer.parseInt(resposta);
      if(rodadas <= 0 ) {
        System.err.println("Forneca um numero positivo, por favor.");
      } else {
        respostaOK = true;
      }
    }

    // MaiorCarta é um jogo onde quem detém a maior carta ganha a rodada
    new MaiorCarta().joga(rodadas);
  } // main
} // Cartas7
/*
 * Desenvolvido para a disciplina Programacao 1
 * Curso de Bacharelado em Ciência da Computação
 * Departamento de Sistemas e Computação
 * Universidade Federal da Paraíba
 *
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 * Não redistribuir sem permissão.
 */

package p1.aplic.cartas;

import java.util.*;

/**
 * Um jogo de cartas simples.
 * Cada jogador recebe uma carta do baralho.
 * A maior carta ganha.
 * Repete para cada rodada.
 *
 * @author Jacques Philippe Sauvé, jacques@dsc.ufpb.br
 * @version 1.0
 * <br>
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 */
public class MaiorCarta {
  private int     suasVitórias;  // pontuação
  private int     minhasVitórias;
  private Baralho baralho;

  /**
   * Construtor do jogo.
   */
   public MaiorCarta() {
    suasVitórias = 0;
    minhasVitórias = 0;
    // Factory method para permitir jogar com outros baralhos
    // com override de criaBaralho()
    baralho = criaBaralho();
    baralho.baralhar();
  }
    
  /**
   * Cria um baralho para jogar.
   * @return O baralho.
   */
  protected Baralho criaBaralho() {
    return new Baralho();
  }

  /**
   * Joga o jogo de Maior Carta.
   * @param rodadas O número de rodadas a jogar.
   */
  public void joga(int rodadas) {
    for(int i = 0; i < rodadas; i++) {
      Carta suaCarta = baralho.pegaCarta();
      System.out.print("Sua carta: " + suaCarta + " ");
      Carta minhaCarta = baralho.pegaCarta();
      System.out.print("Minha carta: " + minhaCarta + " ");
      if(suaCarta.compareTo(minhaCarta) > 0) {
        System.out.println("Voce ganha.");
        suasVitórias++;
      } else if(suaCarta.compareTo(minhaCarta) < 0) {
        System.out.println("Eu ganho.");
        minhasVitórias++;
      } else {
        System.out.println("Empate.");
      }
    }
    System.out.println("Voce ganhou " + suasVitórias +
      " vezes, eu ganhei " + minhasVitórias + " vezes, " +
      (rodadas-suasVitórias-minhasVitórias) + " empates.");
  }
}
Quantas rodadas quer jogar?30
Sua carta: DOIS de PAUS Minha carta: TRES de PAUS Eu ganho.
Sua carta: DOIS de ESPADAS Minha carta: SEIS de ESPADAS Eu ganho.
...
Sua carta: QUATRO de PAUS Minha carta: OITO de OUROS Eu ganho.
Sua carta: CINCO de ESPADAS Minha carta: SETE de ESPADAS Eu ganho.
Sua carta: null Minha carta: null Exception in thread "main" java.lang.NullPointerException
        at p1.aplic.cartas.MaiorCarta.joga(MaiorCarta.java:61)
        at Cartas7.main(Cartas7.java:30)
      if(suaCarta.compareTo(minhaCarta) > 0) { // linha 61

Uma solução: Exceções

  /**
   * Retira uma carta do topo do baralho e a retorna. A carta é removida do baralho.
   * @return A carta retirada do baralho.
   */
  public Carta pegaCarta() throws BaralhoVazioException {
    if(númeroDeCartas() == 0) {
      throw new BaralhoVazioException("Baralho esta vazio");
    }
    return (Carta)baralho.remove(númeroDeCartas()-1);
  }
package p1.aplic.cartas;

/**
 * Classe de Exceção quando tenta-se poegar uma carta de um baralho vazio.
 *
 * @author   Jacques Philippe Sauvé, jacques@dsc.ufpb.br
 * @version 1.1
 * <br>
 * Copyright (C) 2001 Universidade Federal da Paraíba.
 */
public class BaralhoVazioException extends Exception {

  /**
   * Construtor de exceção informando que o baralho está vazio.
   * @param motivo O motivo pelo qual não se pode fechar a conta.
   */
  public BaralhoVazioException(String motivo) {
    super(motivo);
  }
}
/*
 * Desenvolvido para a disciplina Programacao 1
 * Curso de Bacharelado em Ciência da Computação
 * Departamento de Sistemas e Computação
 * Universidade Federal da Paraíba
 *
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 * Não redistribuir sem permissão.
 */

package p1.aplic.cartas;

import java.util.*;

/**
 * Como a classe MaiorCarta, mas tratando de baralho vazio com exceção.
 * Não usa herança para que os alunos possam ver o exemplo antes de ver herança.
 *
 * @author Jacques Philippe Sauvé, jacques@dsc.ufpb.br
 * @version 1.1
 * <br>
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 */
public class MaiorCartaSegura {
  private int     suasVitórias;  // pontuação
  private int     minhasVitórias;
  private int     empates;
  private BaralhoSeguro baralho;

  /**
   * Construtor do jogo.
   */
  public MaiorCartaSegura() {
    suasVitórias = 0;
    minhasVitórias = 0;
    empates = 0;
    // Factory method para permitir jogar com outros baralhos
    // com override de criaBaralho()
    baralho = criaBaralho();
    baralho.baralhar();
  }
    
  /**
   * Cria um baralho para jogar.
   * @return O baralho.
   */
  protected BaralhoSeguro criaBaralho() {
    return new BaralhoSeguro();
  }

  /**
   * Joga o jogo de Maior Carta.
   * @param rodadas O número de rodadas a jogar.
   */
  public void joga(int rodadas) {
    for(int i = 0; i < rodadas; i++) {
      Carta suaCarta, minhaCarta;
      try {
        suaCarta = baralho.pegaCarta();
        minhaCarta = baralho.pegaCarta();
      } catch(BaralhoVazioException e) {
        System.out.println(e.getMessage());
        break;
      }
      System.out.print("Sua carta: " + suaCarta + " ");
      System.out.print("Minha carta: " + minhaCarta + " ");
      if(suaCarta.compareTo(minhaCarta) > 0) {
        System.out.println("Voce ganha.");
        suasVitórias++;
      } else if(suaCarta.compareTo(minhaCarta) < 0) {
        System.out.println("Eu ganho.");
        minhasVitórias++;
      } else {
        System.out.println("Empate.");
        empates++;
      }
    }
    System.out.println("Voce ganhou " + suasVitórias +
      " vezes, eu ganhei " + minhasVitórias + " vezes, " +
      empates + " empates.");
  }
}
/*
 * Para uso em exemplo de exceções
 */

import p1.aplic.cartas.*;
import p1.io.*;

public class Cartas11 {
  public static void main(String[] args) {
    int     rodadas = 0;
    String  resposta;
    boolean respostaOK = false;

    while(!respostaOK) {
      resposta = Entrada.in.lerLinha("Quantas rodadas quer jogar?");
      if(resposta == null) {
        // fim de entrada
        System.exit(0);
      }
      rodadas = Integer.parseInt(resposta);
      if(rodadas <= 0 ) {
        System.err.println("Forneca um numero positivo, por favor.");
      } else {
        respostaOK = true;
      }
    }

    // MaiorCartaSegura é um jogo onde quem detém a maior carta ganha a rodada
    new MaiorCartaSegura().joga(rodadas);
  } // main
} // Cartas11
Quantas rodadas quer jogar?30
Sua carta: DOIS de COPAS Minha carta: DEZ de ESPADAS Eu ganho.
Sua carta: QUATRO de PAUS Minha carta: TRES de OUROS Voce ganha.
...
Sua carta: SEIS de OUROS Minha carta: DAMA de COPAS Eu ganho.
Sua carta: DEZ de OUROS Minha carta: OITO de COPAS Voce ganha.
Baralho esta vazio
Voce ganhou 14 vezes, eu ganhei 11 vezes, 1 empates.
/*
 * Desenvolvido para a disciplina Programacao 1
 * Curso de Bacharelado em Ciência da Computação
 * Departamento de Sistemas e Computação
 * Universidade Federal da Paraíba
 *
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 * Não redistribuir sem permissão.
 */

package p1.aplic.cartas;

import java.util.*;

/**
 * Como a classe MaiorCartaSegura, mas com tratamento de exceção diferente.
 * Não usa herança para que os alunos possam ver o exemplo antes de ver herança.
 *
 * @author Jacques Philippe Sauvé, jacques@dsc.ufpb.br
 * @version 1.0
 * <br>
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 */
public class MaiorCartaSegura2 {
  private int     suasVitórias;  // pontuação
  private int     minhasVitórias;
  private int     empates;
  private BaralhoSeguro baralho;

  /**
   * Construtor do jogo.
   */
  public MaiorCartaSegura2() {
    suasVitórias = 0;
    minhasVitórias = 0;
    empates = 0;
    // Factory method para permitir jogar com outros baralhos
    // com override de criaBaralho()
    baralho = criaBaralho();
    baralho.baralhar();
  }
    
  /**
   * Cria um baralho para jogar.
   * @return O baralho.
   */
  protected BaralhoSeguro criaBaralho() {
    return new BaralhoSeguro();
  }

  /**
   * Joga o jogo de Maior Carta.
   * @param rodadas O número de rodadas a jogar.
   */
  public void joga(int rodadas) throws BaralhoVazioException {
    for(int i = 0; i < rodadas; i++) {
      Carta suaCarta, minhaCarta;
      suaCarta = baralho.pegaCarta();
      minhaCarta = baralho.pegaCarta();
      System.out.print("Sua carta: " + suaCarta + " ");
      System.out.print("Minha carta: " + minhaCarta + " ");
      if(suaCarta.compareTo(minhaCarta) > 0) {
        System.out.println("Voce ganha.");
        suasVitórias++;
      } else if(suaCarta.compareTo(minhaCarta) < 0) {
        System.out.println("Eu ganho.");
        minhasVitórias++;
      } else {
        System.out.println("Empate.");
        empates++;
      }
    }
    System.out.println("Voce ganhou " + suasVitórias +
                       " vezes, eu ganhei " + minhasVitórias + " vezes, " +
                       empates + " empates.");
  }
}
/*
 * Para uso em exemplo de exceções
 */

import p1.aplic.cartas.*;
import p1.io.*;

public class Cartas12 {
  public static void main(String[] args) {
    int     rodadas = 0;
    String  resposta;
    boolean respostaOK = false;
    
    while(!respostaOK) {
      resposta = Entrada.in.lerLinha("Quantas rodadas quer jogar?");
      if(resposta == null) {
          // fim de entrada
          System.exit(0);
      }
      rodadas = Integer.parseInt(resposta);
      if(rodadas <= 0 ) {
        System.err.println("Forneca um numero positivo, por favor.");
      } else {
        respostaOK = true;
      }
    }
    
    // MaiorCartaSegura é um jogo onde quem detém a maior carta ganha a rodada
    try {
      new MaiorCartaSegura2().joga(rodadas);
    } catch(Exception e) {
      System.out.println(e.getMessage());
    }
  } // main
} // Cartas12
Quantas rodadas quer jogar?30
Sua carta: OITO de PAUS Minha carta: OITO de COPAS Empate.
Sua carta: NOVE de OUROS Minha carta: DEZ de COPAS Eu ganho.
...
Sua carta: QUATRO de OUROS Minha carta: CINCO de OUROS Eu ganho.
Sua carta: DAMA de PAUS Minha carta: AS de COPAS Voce ganha.
Baralho esta vazio

Detalhes finais

excecoes.gif (3880 bytes)

package p1.aplic.banco;

/**
 * Classe de Exceção quando tenta-se fechar uma conta sem estar com saldo zerado.
 *
 * @author   Jacques Philippe Sauvé, jacques@dsc.ufpb.br
 * @version 1.1
 * <br>
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 */
public class NaoPodeFecharContaException extends Exception {
  Conta conta;

  /**
   * Construtor de exceção informando que uma conta não pode ser fechada.
   * @param conta A conta que não pode ser fechada.
   * @param motivo O motivo pelo qual não se pode fechar a conta.
   */
  public NaoPodeFecharContaException(Conta conta, String motivo) {
    super(motivo);
    this.conta = conta;
  }
}
package p1.aplic.banco;

import java.util.*;
import java.io.*;
import p1.aplic.geral.*;

/**
 * Classe abstrata de conta bancária com implementações default de alguns métodos.
 *
 * @author   Jacques Philippe Sauvé, jacques@dsc.ufpb.br
 * @version 1.1
 * <br>
 * Copyright (C) 1999 Universidade Federal da Paraíba.
 */
public abstract class Conta implements Serializable {
  // ...
  /**
   * Fecha a conta.
   * @throws NaoPodeFecharContaException Quando se tenta fechar uma conta com saldo não zero.
   */
  public void fechar() throws NaoPodeFecharContaException  {
    Agencia.fecharConta(número);
  }
}
  /**
   * Fecha uma conta.
   * @param número O número da conta a fechar.
   * @throws NaoPodeFecharContaException se a conta não existir ou tiver saldo
   */
  static void fecharConta(int número) throws NaoPodeFecharContaException {
    abrirCaixa();
    Conta c = localizarConta(número);
    if(c == null) {
      throw new NaoPodeFecharContaException(c, "Conta nao existe");
    }
    if(c.getSaldo() != 0.0) {
      throw new NaoPodeFecharContaException(c, "Saldo nao esta zerado");
    }
    contas.remove(Integer.toString(número));
}
  try {
    // trecho que pode lançar várias exceções
  } catch(NaoPodeFecharContaException e) {
    // trata NaoPodeFecharContaException
  } catch(IOException e) {
    // trata IOException
  } catch(Exception e) {
    // trata Exception não capturado acima
  }

oo-6 programa anterior próxima