Página
actualizada às .
Os exercícios incidem sobre as
teóricas da semana anterior. Os enunciados são baseados nos exercício do livro
"Objects First with JAVA" (Primeira Edição).
Projecto shapes (chapter
1)
Crie vários objectos círculo.
Poderá fazê-lo seleccionando new Circle() do menu associado à classe Circle.
Faça com que os círculos criados fiquem visíveis, depois mova-os pela janela de
apresentação utilizando os métodos “move”. Transforme um dos círculos num
círculo grande e amarelo ("yellow"), e outro num círculo pequeno e
verde ("green"). Tente o mesmo com outro tipo de formas geométricas:
crie alguns triângulos e quadrados. Altere as suas posições, tamanhos e
cores.
Tendo em conta os objectos
criados no Exercício 1.7, faça inspecção aos seus estados. Tente alterar o
estado de um objecto (por exemplo, por invocação do método moveLeft) enquanto o
“object inspector” estiver aberto. Deverá observar os valores no “object
inspector” a serem alterados.
Projecto picture (chapter
1)
No código fonte da classe
Picture, encontre a parte que realmente desenha a figura. Altere-a para que o
Sol seja azul em vez de amarelo.
Implemente um método para simular
o pôr-do-sol. De acordo com o exercício 1.15, esse método deverá fazer com que
o Sol na figura se movimente lentamente para baixo. Nesse exercício é sugerida
a utilização do método slowMoveVertical da classe Circle. Assim sendo,
poderemos invocar o método draw para a apresentar a imagem original (com o Sol
no céu) e depois invocar o novo método para simular o pôr-do-sol (sunset).
Projecto lab-classes
(chapter 1)
Crie um objecto da classe
LabClass. Observe a assinatura do construtor. Especifique o número máximo de
alunos na aula criada (um inteiro).
Observe a assinatura do método
enrollStudent e verifique que o parâmetro esperado é do tipo Student. Crie agora
alguns objectos de estudantes (Student). Invoque o método enrollStudent do
objecto instância de LabClass criado anteriormente (Exercício 1.19),
seleccionado o valor a passar ao parâmetro com um click sobre um dos objectos
instância de Student já criados. Faça o mesmo para outros estudantes.
No objecto da classe LabClass
criado no Exercício 1.19, atribua-lhe um docente (instructor), uma sala (room)
e uma hora (time). Invoque o método printList para imprimir a informação
referente à aula, incluindo a lista de alunos inscritos.
Projecto
better-ticket-machine (chapter 2)
Implemente o método empty que
simula o efeito de retirar todo o dinheiro da bilheteira. O método não retorna
nada (void), limitando-se apenas a colocar a zero o valor do campo total. Será
que o método necessita de algum parâmetro? Teste o método empty. Para tal crie
uma bilheteira, insira dinheiro, emita bilhetes, teste o total de dinheiro
inserido e depois retire todo o dinheiro da bilheteira. Considera o método
empty um método mutante?
Implemente o método emptyMachine
que simula o efeito de retirar todo o dinheiro da bilheteira. Este método deve
retornar o total de dinheiro inserido até ao momento, para além de colocar a
zero o valor do campo total.
Como classifica o método
emptyMachine: acessional, mutante ou ambos?
Projecto lab-classes
(chapter 1)
Qual será o valor retornado pelo
método getLoginName de um estudante com nome (name) “José Silva” e número (id)
“
Crie uma estudante chamada “Ana”
com número “
Altere o método getLoginName da
classe Student de forma a gerar sempre um nome de acesso (login name), mesmo
quando os campos do nome (name) e do número (id) não sejam suficientemente
grandes. Para strings menores do que o necessário, utilize toda a string.
Projecto mail-system (chapter 3)
No projecto mail-system (chapter 3) crie uma instância de
MailServer (o servidor de mensagens). Crie depois duas instâncias de
MailClient. Durante a criação das instâncias de MailClient é necessário indicar
a instância do MailServer que lhe fica associado, ou seja o servidor de correio
electrónico do cliente que se está a criar. Para além do servidor, será ainda
necessário especificar o nome do utilizador do cliente de correio electrónico,
ficado cada cliente associado a um único utilizador.
Explore os objectos MailClient criados: experimente enviar mensagens de um
cliente para outro (método sendMessage) e receber mensagens (método
getNextMailItem ou printNextMailItem).
Desenhe um diagrama de objectos que descreva a situação após a criação de
um servidor e de três clientes de correio electrónico. Nota: não se esqueça de
observar o código fonte das diversas classes! (mas não muito...)
Esta sequência de exercícios permite explorar o debugger do BlueJ.
3.23 - Cenário de utilização: criar um servidor de correio electrónico;
criar dois clientes para os utilizadores "Ana" e "Paulo"
(para facilitar a utilização das instâncias, os seus próprios nomes deveriam
ser "ana" e "paulo", respectivamente). Agora envie uma
mensagem do utilizador "Ana" (método sendMessage na instância
"ana") para o utilizador "Paulo". ATENÇÃO: Não leia
já a mensagem na instância "paulo"! Isso vai ser feito nos exercícios
seguintes, mas com utilização do debugger do BlueJ.
3.24 - Ponto de paragem (breakpoint): Edite a classe MailClient e
adicione um breakpoint na primeira linha efectiva do método
printNextMailItem.
3.25 - Passo-a-passo simples (step): Na instância
"paulo" invoque o método printNextMailItem. Observe o valor do estado
de execução da janela do debugger e avance apenas uma linha na execução
do código (botão Step).
3.26 - Questão: Antes de voltar a avançar com o botão Step, preveja qual
será a próxima linha a ser executada. Avance agora mais uma linha com o botão
step. A sua previsão estava certa ou errada? O que é que aconteceu e porquê?
3.27 - Questão: Depois de terminar a execução do método
printNextMailItem do exercício anterior (3.26), volte a invocar este método.
Avance com o debugger sobre o método tal como anteriormente. O que é que
observa? Explique a razão de ter sucedido.
3.28 - Passo-a-passo para dentro de método (step into): Volte a
enviar uma mensagem de Ana para Paulo. Invoque o método printNextMailItem no
cliente "paulo". Desta vez, assim que atingir a linha
item.print() utilize o botão Step Into em vez do botão Step.
Assegure-se que consegue ver a janela de terminal (onde as mensagens são
apresentadas) enquanto avança na execução. O que é que observa? Explique o que
vê.
Coloque um ponto de paragem (breakpoint) na primeira linha efectiva
do método sendMessage da classe MailClient. Invoque agora esse método para
enviar uma mensagem e utilize o botão Step Into da janela do debugger
para entrar dentro do construtor de itens de correio electrónico (MailItem).
Observe agora na janela do debugger as variáveis locais bem como as variáveis
de instância a serem inicializadas à medida que avança na execução
passo-a-passo no construtor. Avance até ao final do método sendMessage podendo
optar por entrar dentro do método post do servidor durante a execução.
Por observação do código fonte, execução integral de métodos, definição de
pontos de paragem e execução de métodos com o debugger, procure entender
as classes MailItem e MailClient. Procure igualmente entender a classe
MailServer, tendo em conta que utiliza conceitos apresentados em capítulos
posteriores ao Capítulo 3, mas já apresentados nas aulas teóricas.
Desenhe diagramas de objectos para explicitar o funcionamento dessas classes.
Projecto auction (chapter 4)
Este projecto implementa um sistema de leilão. A classe Lot representa cada
lote de artigos a serem leiloados. A classe Auction representa um leilão, tendo
informação sobre os lotes a serem leiloados. A classe Person representa as
pessoas que fazem uma licitação (oferta) para comprar um lote. A classe Bid
representa as licitações (ofertas) feitas para um determinado lote.
Procure exemplos de casting nos métodos da classe Auction.
O que acontece se tentar compilar a classe Auction sem um dos casting?
Por exemplo, altere o método showLots de forma a que a primeira instrução do
bloco do ciclo while passe a ser:
Lot lot = it.next();
e teste o resultado da alteração.
Acrescente um novo método à classe Auction chamado close. Este
método deverá percorrer a colecção de lotes (lots) e imprimir os seus
detalhes. Os detalhes referentes aos lotes que já tenham sido vendidos devem
incluir o nome da pessoa que o comprou, bem como o valor pelo qual foi
comprado. Sempre que um lote não tenha sido vendido, deve imprimir-se uma
mensagem que indique esse facto.
Suponha que a classe Auction contém um método que permite a remoção de
lotes. Assumindo que o número de cada um dos restantes lotes (ver campo
number na classe Lot) não é alterado sempre que ocorra uma remoção, qual será o
impacto que esta nova operação teria no método getLot?
Reescreva o método getLot de forma a que este não associe o número de lote
ao índice (número-de-lote -1) na colecção. Poderá assumir que os lotes são
sempre por ordem crescente do seu número de lote.
Acrescente um novo método à classe Auction chamado removeLot, o qual
deverá ter a seguinte assinatura:
/**
* Remove o lote identificado pelo
número de lote.
* @param
number O número do lote a ser removido.
* @return O lote
com o número indicado, ou null no caso de não existir.
*/
public Lot removeLot(int number)
Este método não deverá assumir que um lote com um determinado número está
armazenado numa posição em particular dentro da colecção.
O que é um HashMap? Qual é a sua função e como utilizá-lo? A resposta a
estas questões deve ser feita tendo por base a consulta da documentação da
biblioteca Java.
Crie um novo projecto com uma classe chamada MapTester que utiliza um
HashMap para implementar uma lista telefónica na qual apenas são armazenados os
nomes e os números de telefone de diversas pessoas. Na classe criada implemente
os seguintes métodos:
public void enterNumber(String name, String number) -
que permite inserir na lista telefónica uma nova pessoa e respectivo número de
telefone.
public String lookupNumber(String name) - que permite
obter o número de telefone de uma determinada pessoa.
Estes dois métodos devem utilizar os métodos "put" e
"get" da classe HashMap de forma a implementar a sua funcionalidade.
O que acontece quando se adiciona uma nova entrada (par chave/valor) num
mapa (por exemplo, o HashMap) com uma chave já existente?
O que acontece quando se adiciona uma nova entrada (par chave/valor) num
mapa (por exemplo, o HashMap) com um valor já existente?
Como é que se verifica que uma chave já existe no mapa? Apresente exemplos
do código Java que constem do projecto desta aula.
O que acontece quando se tenta obter um valor cuja chave não existe no
mapa?
Como se obtém o número de entradas (pares chave/valor) de um mapa?
Acrescente comentários de documentação (/** ... */) na classe
MapTester, utilizando os diversos símbolos especiais para formatação (por
exemplo, @param). Utilize a vista "interface" do editor de código
fonte do BlueJ (no botão mais à direita do editor, com opções "implementation"
e "interface", escolher "interface") e veja a
documentação resultante. Utilize ainda a funcionalidade "Project
Documentation" do BlueJ (menu Tools) para gerar a documentação do projecto
em html.
Projecto dome-v2 (chapter 8)
Abra o projecto dome-v2 (versão de DoME com hierarquia de classes).
Observe o diagrama de classes, nomeadamente a hierarquia de classes dos itens
(cd's e vídeos) a inserir na base de dados multimédia. Crie alguns cd's e
alguns vídeos. Crie igualmente um objecto de base de dados (classe Database).
Insira os cd's e os vídeos na base de dados e depois liste o conteúdo da mesma.
Ainda no projecto dome-v2, coloque um ponto de paragem (breakpoint)
na primeira linha do construtor da classe CD. Depois crie um novo objecto da
classe CD. Assim que aparecer a janela do debugger, use o botão Step
Into para avançar ao longo do código fonte. Observe as variáveis de
instância (campos) e sua inicialização. Descreva o que observa.
Adicione uma nova classe para jogos de vídeo ao projecto dome-v2.
Para além dos campos que todos os itens têm, essa classe ainda tem os campos numberOfPlayers
e platform, respectivamente para guardar o número de jogadores e a
plataforma de execução dos jogos de vídeo. Crie alguns objectos dessa nova
classe e teste se todos os seus métodos (incluindo os que são herdados)
funcionam tal como esperado.
Considere as seguintes classes: Pessoa, Professor, Estudante, Doutorando.
Professor e Estudante são ambas subclasses de Pessoa. Doutorando é subclasse de
Estudante.
Quais das seguintes atribuições estão correctas e porquê?
Pessoa p1 = new Estudante();
Pessoa p2 = new Doutorando();
Doutorando d1 = new Estudante();
Professor prof1 = new Pessoa();
Estudante e1 = new Doutorando();
e1 = p1;
e1 = p2;
p1 = e1;
prof1 = e1;
e1 = d1;
d1 = e1;
Teste as suas respostas ao
exercício anterior criando as classes referidas no mesmo e experimentando-as no
BlueJ.