Actividade

  1. Resolução do enunciado da aula.

Objectivos

  1. Concepção de classes em Java que integram alguns conceitos básicos da Programação com Objectos, como a herança e a redefinição de métodos.
  2. Utilização das ferramentas que permitem editar (vi, emacs, etc.), compilar (javac) e executar (java) e depurar (jdb) programas Java.

Enunciado da Aula

Aplicando os conceitos OO que já conhece, concretize as classes necessárias para representar a funcionalidade que se descreve de seguida. Pode ser necessária a criação de classes adicionais não descritas abaixo. A correcta execução dos testes depende da estrita aderência à nomenclatura das classes apresentadas. Todas as classes indicadas devem pertencer à "package" arabiannights.

  1. Funcionalidade da lâmpada mágica (classe MagicLamp):
    Uma lâmpada mágica liberta génios quando esfregada (método rub). Os génios podem ser bem ou mal-humorados. O humor dos génios é determinado pelas condições da lâmpada: sempre que a lâmpada tiver sido esfregada um número par de vezes (sem contar a actual), o génio sai mal-humorado. A quantidade de génios disponíveis é determinada no momento de encantamento da lâmpada (criação). Depois de esgotados os génios disponíveis, já não adianta esfregar a lâmpada para obter um génio, bem ou mal-humorado: nestas condições, a lâmpada cria um pequeno demónio que responde a pedidos de forma literal mas perversa. Devido a requisitos de sustentabilidade ambiental, as normas de produção exigem que as lâmpadas sejam recarregáveis. Assim, é possível voltar a obter génios quando se esfrega a lâmpada (em número igual ao inicial). O processo de recarregamento exige apenas que um demónio seja alimentado à lâmpada (método feedDemon).

    Quando se cria uma nova lâmpada é necessário indicar a quantidade inicial de génios que é possível invocar. É possível saber quantos génios ainda estão disponíveis na lâmpada (método getGenies). É ainda possível saber quantas vezes a lâmpada já foi recarregada (método getDemons). Quando se esfrega a lâmpada, deve-se indicar quantos desejos se espera que o génio realize (independentemente de o génio os poder negar).

    A classe MagicLamp deve saber comparar as suas instâncias (através do método equals). Considera-se que duas lâmpadas são iguais se tiverem a mesma capacidade e se os valores retornados pelos métodos getGenies e getDemons forem iguais.

    Nota: a lâmpada liberta apenas um génio de cada vez.
  2. Funcionalidade do génio bem-humorado (classe FriendlyGenie):
    O génio bem-humorado concede todos os desejos que lhe forem colocados (método grantWish e retorno true), até ao limite com que foi chamado da lâmpada. Depois do limite já não são concedidos desejos (retorno false). É possível saber quantos desejos já foram concedidos (método getGrantedWishes), quantos ainda existem disponíveis (método getRemainingWishes) e se ainda existem disponíveis (método canGrantWish).

    Nota: o génio concede apenas um desejo de cada vez.
  3. Funcionalidade do génio mal-humorado (classe GrumpyGenie):
    O génio mal-humorado concede apenas o primeiro desejo que lhe for colocado (método grantWish e retorno true), independentemente do limite com que foi chamado da lâmpada (retorno false após o primeiro). É possível saber se o desejo já foi realizado (método getGrantedWishes retorna 1).
  4. Funcionalidade do demónio reciclável (classe RecyclableDemon):
    O demónio concede todos os desejos que lhe forem colocados (método grantWish e retorno true), independentemente do limite com que foi chamado da lâmpada. Se o demónio for recolocado na lâmpada (para a recarregar), fica reciclado (método recycle, indicado pelo retorno true do método recycled) e já não pode realizar mais desejos (retorno false). É possível saber quantos desejos já foram concedidos (método getGrantedWishes).

    Nota: o demónio concede apenas um desejo de cada vez.

Todas as classes devem ter métodos de acesso - get e set (quando apropriado) - para os seus atributos.
O método toString, aplicado aos génios e ao demónio, deve devolver uma das seguintes cadeias de caracteres:

  • Friendly genie has granted # wishes and still has # to grant. (# representam os contadores apropriados)
  • Grumpy genie has granted a wish. / Grumpy genie has a wish to grant. (consoante já concedeu ou não o pedido)
  • Recyclable demon has granted # wishes. / Demon has been recycled. (antes e depois de recarregar uma lâmpada)

A classe cliente, de nome ArabianNights , deve possuir um método estático main que execute a seguinte sequência de operações:

  1. Criar uma lâmpada mágica com capacidade para 4 génios.
  2. Esfregar 5 vezes a lâmpada, indicando os números de desejos 2, 3, 4, 5, 1.
  3. Invocar e imprimir o resultado do método toString sobre cada um dos génios.
  4. Pedir um desejo a cada um dos génios.
  5. Invocar e imprimir o resultado do método toString sobre cada um dos génios.
  6. Pedir um desejo a cada um dos génios.
  7. Invocar e imprimir o resultado do método toString sobre cada um dos génios.
  8. Colocar o demónio reciclável na lâmpada.
  9. Esfregar a lâmpada, indicando 7 como número de desejos.
  10. Invocar e imprimir o resultado do método toString sobre o génio obtido.

Testes de Funcionamento

Para este trabalho em grupo, são fornecidos os testes que o trabalho tem de satisfazer por forma a garantir um comportamento correcto. Os testes a executar são fornecidos no ficheiro ap3Tests.jar  para que possam ser executados localmente.

Estes testes assumem a existência de um super-tipo de génio chamado Genie (a natureza exacta não é importante, i.e., pode ser uma classe concreta, uma classe abstracta, ou uma interface).

Para correr os testes na máquina oficial (JUnit 3.8.x), assumindo o JAR correspondente na directoria que contém a solução do problema, executa-se o seguinte comando (no caso de sistemas UNIX):

java -cp /usr/share/java/junit.jar:ap3Tests.jar:. arabiannights.tests.ArabianNights

onde se está a assumir que o arquivo junit.jar está guardado em "/usr/share/java". Caso não seja esse o caso deve ser indicado o caminho correcto. Caso não tenha ainda a framework de testes JUnit, pode utilizar esta versão: junit.jar. Caso o junit.jar e ap3Tests.jar estejam na directoria que contém a solução do problema, o comando deverá ser:

java -cp junit.jar:ap3Tests.jar:. arabiannights.tests.ArabianNights

No caso de sistemas Windowns, o comando é ligeiramente diferente porque o separador de directorias em Windows é o caracter ';' e não ':'. Assim, o comando deverá ser:

java -cp /caminho/para/junit.jar;ap3Tests.jar;. arabiannights.tests.ArabianNights

Note-se que, antes de se executarem os testes, já devem ter sido concretizadas e compiladas sem erros as classes pedidas no enunciado.

Testes de Funcionamento

Para este trabalho em grupo, são fornecidos os testes que o trabalho tem de satisfazer por forma a garantir um comportamento correcto. Os testes a executar são fornecidos no ficheiro ap3Tests.jar  para que possam ser executados localmente.

Estes testes assumem a existência de um super-tipo de génio chamado Genie (a natureza exacta não é importante, i.e., pode ser uma classe concreta, uma classe abstracta, ou uma interface).

Para correr os testes na máquina oficial (JUnit 3.8.x), assumindo o JAR correspondente na directoria que contém a solução do problema, executa-se o seguinte comando (no caso de sistemas UNIX):

java -cp /usr/share/java/junit.jar:ap3Tests.jar:. arabiannights.tests.ArabianNights

onde se está a assumir que o arquivo junit.jar está guardado em "/usr/share/java". Caso não seja esse o caso deve ser indicado o caminho correcto. Caso não tenha ainda a framework de testes JUnit, pode utilizar esta versão: junit.jar. Caso o junit.jar e ap3Tests.jar estejam na directoria que contém a solução do problema, o comando deverá ser:

java -cp junit.jar:ap3Tests.jar:. arabiannights.tests.ArabianNights

No caso de sistemas Windowns, o comando é ligeiramente diferente porque o separador de directorias em Windows é o caracter ';' e não ':'. Assim, o comando deverá ser:

java -cp /caminho/para/junit.jar;ap3Tests.jar;. arabiannights.tests.ArabianNights

Note-se que, antes de se executarem os testes, já devem ter sido concretizadas e compiladas sem erros as classes pedidas no enunciado.

Enunciado do Exercício 2 (EP2)

Comentar, usando o javadoc todo o código referente ao exercício realizado na aula prática nº 3. Os comentários devem incidir sobre os cabeçalhos das classes e dos respectivos métodos.

Entregas via Web

Além de executar os testes, deve entregar eletronicamente no Fenix o seu trabalho.

Para realizar a entrega deve fazer o seguinte: após obter as classes que obedeçam às especificações fornecidas, crie o ficheiro ap3.jar, contendo apenas os ficheiros fonte (.java) de todas as classes concretizadas. Se todas as classes estiverem na package pacote, deve ser dado o seguinte comando:

jar cvf ap3.jar pacote

De seguida, entregar o ficheiro ap3.jar. O trabalho pode ser entregue várias vezes, até à data limite de entrega, sendo considerada apenas a última versão.

Endereço para entregas: o Fenix (secção Avaliação)