Orientação a Objetos – Criação de Classes – Parte II

Programação 2 – Aulas 10 e 11

Objetivos da seção

Continuar pensando em testes antes de definir novas classes

Aprender a definir novas classes mais sofisticadas

     Revisão de alguns conceitos, como escopo de atributos e variáveis locais, sobrecarga de métodos, métodos de classe, atributos de classe, escopo de atributos de classe, constantes

Mais exemplos de classes

Vamos ver a implementação de duas classes que já usamos: Carta e Baralho

Os testes da classe Carta

Eis alguns testes que indicam como queremos que a classe Carta de comporte

package p1.aplic.cartas.testes;

 

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

 

import p1.aplic.cartas.Baralho;

import p1.aplic.cartas.Carta;

 

 

public class TestaCarta {

   private Carta asPaus;

   private Carta asCopas;

   private Carta reiPaus;

   private Carta menorCarta;

   private Carta maiorCarta;

 

   @Before

   public void criaCartas() {

      asPaus = new Carta(Carta.AS, Carta.PAUS);

      asCopas = new Carta(Carta.AS, Carta.COPAS);

      reiPaus = new Carta(Carta.REI, Carta.PAUS);

      menorCarta = new Carta(Carta.menorValor(), Carta.PAUS);

      maiorCarta = new Carta(Carta.maiorValor(), Carta.PAUS);

   }

 

   @Test

   public void testEquals() {

      Assert.assertTrue(!asPaus.equals(null));

      Assert.assertTrue(!asPaus.equals(new Baralho()));

      Assert.assertEquals(asPaus, asPaus);

      Assert.assertEquals(new Carta(Carta.AS, Carta.PAUS), asPaus);

      Assert.assertTrue(!asPaus.equals(asCopas));

      Assert.assertTrue(!asPaus.equals(reiPaus));

   }

 

   @Test

   public void testMenor() {

      Assert.assertEquals(asPaus, menorCarta);

   }

 

   @Test

   public void testMaior() {

      Assert.assertEquals(reiPaus, maiorCarta);

   }

 

   @Test

   public void testCompareTo() {

      Assert.assertEquals("1", 0, asPaus.compareTo(asPaus));

      Assert.assertEquals("2", 0, asPaus.compareTo(new Carta(Carta.AS, Carta.PAUS)));

      Assert.assertEquals("3", 0, asPaus.compareTo(asCopas));

      Assert.assertTrue("4", asPaus.compareTo(reiPaus) < 0);

      Assert.assertTrue("5", reiPaus.compareTo(asPaus) > 0);

   }

 

   @Test

   public void testToString() {

      Assert.assertTrue(asPaus.toString().equals("AS de PAUS"));

   }

}

A classe Carta

package p1.aplic.cartas;

 

public class Carta {

 

   /**

    * Valor da carta AS. Usado para construir uma carta: new Carta(Carta.AS,

    * Carta.PAUS)

    */

   public static final int AS = 1;

 

   /**

    * Valor da carta VALETE. Usado para construir uma carta: new

    * Carta(Carta.VALETE, Carta.PAUS)

    */

   public static final int VALETE = 11;

 

   /**

    * Valor da carta DAMA. Usado para construir uma carta: new

    * Carta(Carta.DAMA, Carta.PAUS)

    */

   public static final int DAMA = 12;

 

   /**

    * Valor da carta REI. Usado para construir uma carta: new

    * Carta(Carta.REI, Carta.PAUS)

    */

   public static final int REI = 13;

 

   /**

    * Valor do naipe de PAUS. Usado para construir uma carta: new

    * Carta(Carta.AS, Carta.PAUS)

    */

   public static final int PAUS = 0;

 

   /**

    * Valor do naipe de OUROS. Usado para construir uma carta: new

    * Carta(Carta.AS, Carta.OUROS)

    */

   public static final int OUROS = 1;

 

   /**

    * Valor do naipe de COPAS. Usado para construir uma carta: new

    * Carta(Carta.AS, Carta.COPAS)

    */

   public static final int COPAS = 2;

 

   /**

    * Valor do naipe de ESPADAS. Usado para construir uma carta: new

    * Carta(Carta.AS, Carta.ESPADAS)

    */

   public static final int ESPADAS = 3;

 

   private int valor;

   private int naipe;

 

   /**

    * Construtor de uma carta comum.

    *

    * @param valor

    *            O valor da carta (AS, 2, 3, ..., 10, VALETE, DAMA, REI).

    * @param naipe

    *            O naipe da carta (PAUS, OUROS, COPAS, ESPADAS).

    */

   public Carta(int valor, int naipe) {

      this.valor = valor;

      this.naipe = naipe;

   }

 

   /**

    * Recupera o valor da carta.

    *

    * @return O valor da carta.

    */

   public int getValor() {

      return valor;

   }

 

   /**

    * Recupera o naipe da carta.

    *

    * @return O naipe da carta.

    */

   public int getNaipe() {

      return naipe;

   }

 

   /**

    * Recupera o valor da menor carta deste tipo que pode ser criada. É

    * possível fazer um laço de menorValor() até maiorValor() para varrer

    * todos os valores possíveis de cartas.

    *

    * @return O menor valor.

    */

   public static int menorValor() {

      return AS;

   }

 

   /**

    * Recupera o valor da maior carta deste tipo que pode ser criada. É

    * possível fazer um laço de menorValor() até maiorValor() para varrer

    * todos os valores possíveis de cartas.

    *

    * @return O maior valor.

    */

   public static int maiorValor() {

      return REI;

   }

 

   /**

    * Recupera o "primeiro naipe" das cartas deste tipo. Ser "primeiro naipe"

    * não significa muita coisa, que naipes não tem valor (um naipe não é

    * menor ou maior que o outro). Fala-se de "primeiro naipe" e "último

    * naipe" para poder fazer um laço de primeiroNaipe() até últimoNaipe()

    * para varrer todos os naipes possíveis de cartas.

    *

    * @return O primeiro naipe.

    */

   public static int primeiroNaipe() {

      return PAUS;

   }

 

   /**

    * Recupera o "último naipe" das cartas deste tipo. Ser "último naipe" não

    * significa muita coisa, que naipes não tem valor (um naipe não é

    * menor ou maior que o outro). Fala-se de "primeiro naipe" e "último

    * naipe" para poder fazer um laço de primeiroNaipe() até últimoNaipe()

    * para varrer todos os naipes possíveis de cartas.

    *

    * @return O primeiro naipe.

    */

   public static int últimoNaipe() {

      return ESPADAS;

   }

 

   /**

    * Compare esta carta a outra.

    *

    * @param outra

    *            A carta a comparar a esta.

    * @return Zero se forem iguais. Um valor < 0 se a carta for menor que a

    *         outra carta. Um valor > 0 se a carta for maior que a outra  
   
*         carta.

    */

   public int compareTo(Carta outra) {

      return getValor() - outra.getValor();

   }

 

   /**

    * Testa a igualdade de um objeto com esta carta.

    *

    * @param objeto

    *            O objeto a comparar com esta carta.

    * @return true se o objeto for igual a esta carta, false caso contrário.

    */

   public boolean equals(Object objeto) {

      if (!(objeto instanceof Carta)) {

         return false;

      }

      Carta outra = (Carta) objeto;

      return getValor() == outra.getValor() &&
             getNaipe() == outra.getNaipe();

   }

 

   private static final String[] nomeDeCarta = {

         "", // queremos sincronizar o valor da carta e seu indice (AS == 1,

         // etc.)

         "AS", "DOIS", "TRES", "QUATRO", "CINCO", "SEIS", "SETE", "OITO",

         "NOVE", "DEZ", "VALETE", "DAMA", "REI", };

 

   private static final String[] nomeDeNaipe = { "PAUS", "OUROS", "COPAS",

         "ESPADAS"};

 

   /**

    * Representa a carta como String.

    *

    * @return Um string representando a carta.

    */

   public String toString() {

      return nomeDeCarta[getValor()] + " de " + nomeDeNaipe[getNaipe()];

   }

}

Verifique a definição de certas cartas (AS, REI, ...) e a definição dos naipes

     São constantes simbólicas

     Por convenção, usamos letras maiúsculas para constantes simbólicas

     A palavra “final” diz que são constantes (o valor é final e não pode mudar)

     A palavra "static" diz que isso pertence à classe e não precisa ser armazenado para cada objeto da classe

i)    Observe que uso o nome da classe antes do "." e não uma referência a um objeto

ii)Isso é por causa do "static"

     A palavra "public" siz que posso usar Carta.AS, Carta.OUROS, mesmo fora da classe

Poderíamos ter usado um String para os naipes, em vez de usar int, certo?

     Qual você prefere?

     O que mudaria no programa?

Quais são os atributos de cada objeto da classe Carta?

O método menorValor() também é static

     Ele só acessa informaão estática, então pode ser static

     Serve para que eu possa fazer Carta.MenorValor() e saber o menor valor que existe nas Cartas sem ter que instanciar um objeto primeiro

     Chamamos isso de método de classe, ou método estático

     Embora tenham seu lugar, métodos de classe devem ser evitados

O método compareTo() existe em muitas classes e serve para poder comparar dois objetos

     Vamos supor que eu tenha duas cartas que peguei de um Baralho

     As cartas têm referências suaCarta e minhaCarta

     Então posso fazer o seguinte dentro de um programa:

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.");

}

Observe como o método toString() é simples

     São os arrays de nomes que simplificam tudo

     Como você teria feito? Com muito código usando if-else ou switch??

Como teste de conhecimento, o que ocorreria se os arrays nomeDeCarta e nomeDeNaipe não fossem estáticos?

Existem testes que faltam ser realizados?

Agora vamos ver uma implementação diferente para Carta

Palavra reservada enum

Surgiu na versão SE5 de Java

Torna nossa vida mais simples quando precisamos agrupar itens e usá-los como um conjunto de tipos enumerados

Substitui um monte de definições de constantes estáticas

     Melhor porque limita os valores possíveis aos valores enumerados explicitamente. Isto é, restringe os valores que se pode atribuir ao tipo enumerado

Representa uma série de objetos com nome

Pode ter métodos, construtores, atributos como qualquer classe

Vamos mudar a classe Carta para usar enum?

package p1.aplic.cartas;

 

public class Carta {

 

       /**

        * Valores possíveis para as cartas. Usada para construir uma carta:

        * new Carta(ValorDeCarta.AS, NaipeDeCarta.PAUS)

        */

       public static enum ValorDeCarta {

               AS(1), DOIS(2), TRES(3), QUATRO(4), CINCO(5), SEIS(6),

               SETE(7), OITO(8), NOVE(9), DEZ(10), VALETE(11), DAMA(12),

               REI(13);

 

               private int valorCarta;

 

               ValorDeCarta(int valor) {

                       valorCarta = valor;

               }

 

               public int getValor() {

                       return valorCarta;

               }

 

       };

 

       /**

        * Naipes possíveis para as cartas. Usada para construir uma carta:

        * new Carta(ValorDeCarta.AS, NaipeDeCarta.PAUS)

        */

       public static enum NaipeDeCarta {

               PAUS, OUROS, COPAS, ESPADAS

       };

 

       private ValorDeCarta valor;

 

       private NaipeDeCarta naipe;

 

       /**

        * Construtor de uma carta comum.

        *

        * @param valor

        *            O valor da carta (AS, 2, 3, ..., 10, VALETE, DAMA,

        *            REI).

        * @param naipe

        *            O naipe da carta (PAUS, OUROS, COPAS, ESPADAS).

        */

       public Carta(ValorDeCarta valor, NaipeDeCarta naipe) {

               this.valor = valor;

               this.naipe = naipe;

       }

 

       /**

        * Recupera o valor da carta.

        *

        * @return O valor da carta.

        */

       public int getValor() {

               return valor.getValor();

       }

 

       /**

        * Recupera o naipe da carta.

        *

        * @return O naipe da carta.

        */

       public int getNaipe() {

               return naipe.ordinal();

       }

 

       /**

        * Recupera o valor da menor carta deste tipo que pode ser criada. É

        * possível fazer um laço de menorValor() até maiorValor() para

        * varrer todos os valores possíveis de cartas.

        *

        * @return O menor valor.

        */

       public static ValorDeCarta menorValor() {

               return ValorDeCarta.AS;

       }

 

       /**

        * Recupera o valor da maior carta deste tipo que pode ser criada. É

        * possível fazer um laço de menorValor() até maiorValor() para

        * varrer todos os valores possíveis de cartas.

        *

        * @return O maior valor.

        */

       public static ValorDeCarta maiorValor() {

               return ValorDeCarta.REI;

       }

 

       /**

        * Recupera o "primeiro naipe" das cartas deste tipo. Ser "primeiro

        * naipe" não significa muita coisa, que naipes não tem valor (um

        * naipe não é menor ou maior que o outro). Fala-se de "primeiro

        * naipe" e "último naipe" para poder fazer um laço de

        * primeiroNaipe() até últimoNaipe() para varrer

        * todos os naipes possíveis de cartas.

        *

        * @return O primeiro naipe.

        */

       public static NaipeDeCarta primeiroNaipe() {

               return NaipeDeCarta.PAUS;

       }

 

       /**

        * Recupera o "último naipe" das cartas deste tipo. Ser "último

        * naipe" não significa muita coisa, que naipes não tem valor (um

        * naipe não é menor ou maior que o outro). Fala-se de "primeiro

        * naipe" e "último naipe" para poder fazer um laço de

        * primeiroNaipe() até últimoNaipe() para varrer

        * todos os naipes possíveis de cartas.

        *

        * @return O primeiro naipe.

        */

       public static NaipeDeCarta últimoNaipe() {

               return NaipeDeCarta.ESPADAS;

       }

 

       /**

        * Compare esta carta a outra.

        *

        * @param outra

        *            A carta a comparar a esta.

        * @return Zero se forem iguais. Um valor < 0 se a carta for menor

        *         que a outra carta. Um valor > 0 se a carta for maior

        *         que a outra carta.

        */

       public int compareTo(Carta outra) {

               return getValor() - outra.getValor();

       }

 

       /**

        * Testa a igualdade de um objeto com esta carta.

        *

        * @param objeto

        *            O objeto a comparar com esta carta.

        * @return true se o objeto for igual a esta carta, false caso

        *         contrário.

        */

       public boolean equals(Object objeto) {

               if (!(objeto instanceof Carta)) {

                       return false;

               }

               Carta outra = (Carta) objeto;

               return getValor() == outra.getValor() &&

                      getNaipe() == outra.getNaipe();

       }

 

       /**

        * Representa a carta como String.

        *

        * @return Um string representando a carta.

        */

       public String toString() {

               return valor + " de " + naipe;

       }

}

Os testes são praticamente os mesmos, só muda a forma de criar as cartas

     Não recebe mais int, recebe valores dos tipos enumerados ValorDeCarta e NaipeDeCarta

package p1.aplic.cartas.testes;

 

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

 

import p1.aplic.cartas.Carta;

import p1.aplic.cartas.Carta.NaipeDeCarta;

import p1.aplic.cartas.Carta.ValorDeCarta;

 

 

public class TestaCarta {

       private Carta asPaus;

       private Carta asCopas;

       private Carta reiPaus;

       private Carta menorCarta;

       private Carta maiorCarta;

 

       @Before

       public void criaCartas() {

               asPaus = new Carta(ValorDeCarta.AS, NaipeDeCarta.PAUS);

               asCopas = new Carta(ValorDeCarta.AS, NaipeDeCarta.COPAS);

               reiPaus = new Carta(ValorDeCarta.REI, NaipeDeCarta.PAUS);

               menorCarta = new Carta(Carta.menorValor(),

                                      NaipeDeCarta.PAUS);

               maiorCarta = new Carta(Carta.maiorValor(),

                                      NaipeDeCarta.PAUS);

       }

 

  @Test

       public void testEquals() {

               Assert.assertTrue(!asPaus.equals(null));

               Assert.assertTrue(!asPaus.equals("AS de PAUS"));

               Assert.assertEquals(asPaus, asPaus);

               Assert.assertEquals(new Carta(ValorDeCarta.AS,

                                   NaipeDeCarta.PAUS), asPaus);

               Assert.assertTrue(!asPaus.equals(asCopas));

               Assert.assertTrue(!asPaus.equals(reiPaus));

       }

 

  @Test

       public void testMenor() {

               Assert.assertEquals(asPaus, menorCarta);

       }

 

  @Test

       public void testMaior() {

               Assert.assertEquals(reiPaus, maiorCarta);

       }

 

  @Test

       public void testCompareTo() {

               Assert.assertEquals("1", 0, asPaus.compareTo(asPaus));

               Assert.assertEquals("2", 0, asPaus.compareTo(

                        new Carta(ValorDeCarta.AS, NaipeDeCarta.PAUS)));

               Assert.assertEquals("3", 0, asPaus.compareTo(asCopas));

               Assert.assertTrue("4", asPaus.compareTo(reiPaus) < 0);

               Assert.assertTrue("5", reiPaus.compareTo(asPaus) > 0);

       }

 

  @Test

       public void testToString() {

               Assert.assertTrue(asPaus.toString().equals("AS de PAUS"));

       }

}

 

Os testes da classe Baralho

Primeiro, vamos ver o que Baralho promete oferecer na sua interface:

     Clique aqui e veja o construtor e os métodos prometidos

Agora, os testes ...

package p1.aplic.cartas.testes;

 

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

 

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

 

import p1.aplic.cartas.Baralho;

import p1.aplic.cartas.Carta;

import p1.aplic.cartas.Carta.ValorDeCarta;

 

public class TestaBaralho {

   private Baralho baralho1; // fica intacto

 

   @Before

   public void criaBaralho() {

      baralho1 = new Baralho();

   }

 

   @Test

   public void testNúmeroDeCartas() {

      Assert.assertEquals(ValorDeCarta.AS, baralho1.menorValor());

      Assert.assertEquals(ValorDeCarta.REI, baralho1.maiorValor());

      Assert.assertEquals(52, baralho1.númeroDeCartas());

   }

 

   @Test

   public void testBaralhoNovo() {

      Assert.assertTrue(baralhoEstáCompleto(baralho1));

   }

 

   @Test

   public void testBaralhar() {

      // Baralho b2 = new Baralho();

      baralho1.baralhar();

      Assert.assertTrue(baralhoEstáCompleto(baralho1));

   }

 

   private boolean baralhoEstáCompleto(Baralho b) {

      List<Carta> cartasJáVistas = new ArrayList<Carta>();

      Iterator<Carta> it = b.iterator();

      while (it.hasNext()) {

         Carta c = (Carta) it.next();

         // vê se carta está ok

         int v = c.getValor();

         int n = c.getNaipe();

         Assert.assertTrue("Valor não ok", v >= Carta.menorValor().getValor()

               && v <= Carta.maiorValor().getValor());

         Assert.assertTrue("Naipe não ok",

                                n >= Carta.primeiroNaipe().ordinal()

                                && n <= Carta.últimoNaipe().ordinal());

         Assert.assertTrue("Carta já vista", !cartasJáVistas.contains(c));

         cartasJáVistas.add(c);

      }

      return cartasJáVistas.size() == 52;

   }

 

   @Test

   public void testPegaCarta() {

      List<Carta> cartasJáVistas = new ArrayList<Carta>();

      Baralho b3 = new Baralho();

      Carta c;

      while ((c = b3.pegaCarta()) != null) {

         // vê se carta está ok

         int v = c.getValor();

         int n = c.getNaipe();

         Assert.assertTrue("Valor não ok", v >= Carta.menorValor().getValor()

               && v <= Carta.maiorValor().getValor());

         Assert.assertTrue("Naipe não ok",

                           n >= Carta.primeiroNaipe().ordinal()

                           && n <= Carta.últimoNaipe().ordinal());

         Assert.assertTrue("Carta já vista", !cartasJáVistas.contains(c));

         cartasJáVistas.add(c);

      }

      Assert.assertEquals("Baralho não vazio", 0, b3.númeroDeCartas());

   }

}

A classe Baralho

Primeiro, vamos ver novamente o que Baralho promete oferecer na sua interface:

     Clique aqui e veja o construtor e os métodos prometidos

Agora, vejamos como implementar Baralho.java

package p1.aplic.cartas;

 

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import p1.aplic.cartas.Carta.NaipeDeCarta;

import p1.aplic.cartas.Carta.ValorDeCarta;

 

/**

 *

 * Um baralho comum de cartas. Num baralho comum, tem 52 cartas: 13 valores

 * (AS,2, 3, ..., 10, valete, dama, rei) de 4 naipes (ouros, espadas, copas,

 * paus).

 *

 * @author Jacques Philippe Sauvé, jacques@dsc.ufpb.br

 * @author Raquel Lopes, raquel@dsc.ufpb.br

 *

 * @version 2.0 <br>

 *

 *          Copyright (C) 1999 Universidade Federal de Campina Grande.

 */

 

public class Baralho {

 

   /**

    *

    * O baralho é armazenado aqui.

    */

 

   private List<Carta> baralho;

 

   /**

    *

    * Construtor de um baralho comum.

    */

 

   public Baralho() {

 

      // Usa uma List para ter um iterador facilmente

      baralho = new ArrayList<Carta>();

 

      // enche o baralho

      ValorDeCarta[] valores = ValorDeCarta.values();

 

      for (int i = 0; i < valores.length; i++) {

 

         NaipeDeCarta[] naipes = NaipeDeCarta.values();

 

         for (int j = 0; j < naipes.length; j++) {

 

            baralho.add(new Carta(valores[i], naipes[j]));

 

         }

 

      }

 

   }

 

   /**

    *

    * Recupera o valor da menor carta possível deste baralho. É possível

    * fazer um laço de menorValor() até maiorValor() para varrer todos os

    * valores possíveis de cartas.

    *

    *

    *

    * @return O menor valor.

    */

 

   public ValorDeCarta menorValor() {

 

      return Carta.menorValor();

 

   }

 

   /**

    *

    * Recupera o valor da maior carta possível deste baralho. É possível

    * fazer um laço de menorValor() até maiorValor() para varrer todos os

    * valores possíveis de cartas.

    *

    *

    *

    * @return O maior valor.

    */

 

   public ValorDeCarta maiorValor() {

 

      return Carta.maiorValor();

 

   }

 

   /**

    *

    * Recupera o "primeiro naipe" das cartas que podem estar no baralho. Ser

    * "primeiro naipe" não significa muita coisa, que naipes não tem valor

    * (um naipe não é menor ou maior que o outro). Fala-se de "primeiro

    * naipe" e "último naipe" para poder fazer um laço de primeiroNaipe() até

    * últimoNaipe() para varrer todos os naipes possíveis de cartas.

    *

    * @return O primeiro naipe.

    */

 

   public NaipeDeCarta primeiroNaipe() {

 

      return Carta.primeiroNaipe();

 

   }

 

   /**

    *

    * Recupera o "último naipe" das cartas que podem estar no baralho. Ser

    * "último naipe" não significa muita coisa, que naipes não tem valor

    * (um naipe não é menor ou maior que o outro). Fala-se de "primeiro

    * naipe" e "último naipe" para poder fazer um laço de primeiroNaipe() até

    * últimoNaipe() para varrer todos os naipes possíveis de cartas.

    *

    * @return O primeiro naipe.

    */

 

   public NaipeDeCarta últimoNaipe() {

 

      return Carta.últimoNaipe();

 

   }

 

   /**

    *

    * Recupera o número de cartas atualmente no baralho.

    *

    * @return O número de cartas no baralho.

    */

 

   public int númeroDeCartas() {

 

      return baralho.size();

 

   }

 

   /**

    *

    * Baralha (traça) o baralho.

    */

 

   public void baralhar() {

 

      for (int posição = 0; posição < númeroDeCartas() - 1; posição++) {

 

         // escolhe uma posição aleatória entre posição e númeroDeCartas()-1

 

         int posAleatória = posição +

                 (int) ((númeroDeCartas() - posição) * Math.random());

 

         // troca as cartas em posição e posAleatória

 

         Carta temp = baralho.get(posição);

 

         baralho.set(posição, baralho.get(posAleatória));

 

         baralho.set(posAleatória, temp);

 

      }

 

   }

 

   /**

    *

    * Retira uma carta do topo do baralho e a retorna. A carta é removida do

    *

    * baralho.

    *

    * @return A carta retirada do baralho.

    */

 

   public Carta pegaCarta() {

 

      if (númeroDeCartas() == 0)

 

         return null;

 

      return baralho.remove(númeroDeCartas() - 1);

 

   }

 

   /**

    *

    * Retorna um iterador do baralho.

    *

    * @return Um iterador que itera sobre as cartas do baralho.

    */

 

   public Iterator<Carta> iterator() {

 

      return baralho.iterator();

 

   }

 

}

Observações sobre a classe Baralho

Estude como o Construtor funciona

     Os dois “for” usam o método estático values() de Enum

Veja como menorValor() usa menorValor() da Carta

     O menor valor de um Baralho cheio é o menor valor das Cartas que compõem o baralho, certo?

Veja a implementação do método númeroDeCartas()

Veja a implementação do método iterator()

Veja o uso de variáveis locais: posição, posiçãoAleatória, i, j, valores, naipes...

Veja a implementação da método baralhar(): é muito instrutivo

     Math.random() retorna um número randômico (ou pseudo-randômico) na faixa [0,1)

Veja a implementação do método pegaCarta()

     É bom ter uma forma de avisar que não sobrou nada no Baralho, certo

     Claro que é bom que o chamador verifique isso!!

     Já vimos o que deveria ocorrer quando pegaCarta() é chamado com Baralho vazio (uma exceção)

Em UML, temos o seguinte:

     O losango chama-se agregação (um Baralho "possui" Cartas)

     Usado para indicar uma relação de "todo-parte"

     0..* chama-se a cardinalidade e indica que um baralho pode ter 0 ou mais Cartas

 

             

A classe MaiorCarta

Se tiver tempo, estudar MaiorCarta em aula, senão o aluno estuda em casa

Já vimos este jogo antes

O programa está a seguir

/*

 * Desenvolvido para a disciplina Programacao 1

 * Curso de Bacharelado em Ciência da Computação

 * Departamento de Sistemas e Computação

 * Universidade Federal de Campina Grande

 *

 * Copyright (C) 1999 Universidade Federal de Campina Grande.

 * Não redistribuir sem permissão.

 */

 

package p1.aplic.cartas;

 

/**

 * 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 de Campina Grande.

 */

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;

      baralho = new Baralho();

      baralho.baralhar();

   }

 

   /**

    * 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 && baralho.númeroDeCartas() > 0; 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.");

   }

}

 

Jogando o jogo ...

Segue um programa simples que joga o jogo MaiorCarta

package p2.exemplos;

 

import p1.aplic.cartas.*;

 

public class Exemplo2 {

   public static void main(String args[]) {

      final int NUM_RODADAS = 15;

      (new MaiorCarta()).joga(NUM_RODADAS);

   }

}

Uma possível saída do programa segue:

Sua carta: NOVE de COPAS Minha carta: VALETE de COPAS Eu ganho.

Sua carta: SEIS de COPAS Minha carta: DEZ de ESPADAS Eu ganho.

Sua carta: NOVE de ESPADAS Minha carta: REI de COPAS Eu ganho.

Sua carta: SEIS de PAUS Minha carta: TRES de PAUS Voce ganha.

Sua carta: TRES de OUROS Minha carta: TRES de COPAS Empate.

Sua carta: REI de ESPADAS Minha carta: CINCO de PAUS Voce ganha.

Sua carta: OITO de OUROS Minha carta: QUATRO de PAUS Voce ganha.

Sua carta: VALETE de OUROS Minha carta: SETE de ESPADAS Voce ganha.

Sua carta: SETE de OUROS Minha carta: TRES de ESPADAS Voce ganha.

Sua carta: SETE de PAUS Minha carta: DOIS de ESPADAS Voce ganha.

Sua carta: AS de OUROS Minha carta: AS de COPAS Empate.

Sua carta: REI de PAUS Minha carta: AS de ESPADAS Voce ganha.

Sua carta: CINCO de OUROS Minha carta: OITO de COPAS Eu ganho.

Sua carta: DAMA de ESPADAS Minha carta: QUATRO de ESPADAS Voce ganha.

Sua carta: OITO de ESPADAS Minha carta: REI de OUROS Eu ganho.

Voce ganhou 8 vezes, eu ganhei 5 vezes, 2 empates.

Veja como objeto de uma classe usa objetos de outra classe e assim sucessivamente

Em UML, temos:

 

ProgramaHP da disciplina