aluno: Thiago Brandão Damasceno
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 06/08/2008 (2)
Introdução
O objetivo deste laboratório foi introduzir princípios básicos de programação orientada a objetos, tais como encapsulamento, herança e polimorfismo. Toda a programação foi realizada com auxílio do BlueJ, uma IDE para Java desenvolvida para aulas introdutórias na linguagem.
Desenvolvimento
Construção das classes
Após a análise do diagrama UML representativo das classes do modelo de entrega e execução de relatórios, a primeira parte do laboratório consistiu em traduzir para a sintaxe de Java as relações entre as diversas classes, estabelecendo seus atributos e seus métodos. Abaixo segue os códigos-fonte das classes criadas. Os comentários explicam a dinâmica das mesmas.
1) Classe Aluno
//classe abstrata Aluno //esta classe irá servir de base para criar dois tipos diferentes de aluno: //um aluno safo , cuja classe é AlunoSafoPreguicoso e um aluno esforçado cuja classe é AlunoEsforcado //esta classe não pode ser utilizada para instanciar objetos, daí o nome abstrata //com esse tipo de metodologia, é possível separar em módulos o que se trata de uma característica //geral de um aluno e o que se trata de uma característica particular. public abstract class Aluno { //atributos gerais de todo aluno (objeto da classe Aluno) private int conhecimento = 0; private String nome; private RelaQueue relaq; //métodos que qualquer objeto das classes que herdam Aluno //pode chamar (AlunoSafoPreguicoso e AlunoEsforcado) public Aluno(String nm, RelaQueue rl) //construtor da classe Aluno { nome = nm; //nome do aluno relaq = rl; //fila de relatórios a que deve submeter o seu relatório } public String getNome() //retorna o nome do aluno na forma de objeto String { return nome; } public void fazEEntregaRelatorio() //função que reproduz o efeito da execução e entrega do relatório { //calcula qualidade e originalidade com base na inteligencia e dedicacao float qualidade = (2*this.getDedicacao() + this.getInteligencia())/3; float originalidade = (this.getDedicacao() + 2*this.getInteligencia())/3; //cria relatório com referência ao próprio objeto (aluno) Relatorio rela = new Relatorio(qualidade, originalidade, this); relaq.queue(rela); //coloca na fila conhecimento++; //aumenta a variável conhecimento } public int getConhecimento() //retorna conhecimento { return conhecimento; } //métodos abstratos: esses métodos devem sofrer override //nas classes-filhas de Aluno abstract float getInteligencia(); abstract float getDedicacao(); }
2) Classe AlunoSafoPreguicoso
import java.util.*; //o aluno do tipo AlunoSafoPreguicoso herda todos //os atributos e os métodos(não abstratos) da classe Aluno public class AlunoSafoPreguicoso extends Aluno { private float inteligencia; public AlunoSafoPreguicoso(String nm, RelaQueue rl) //construtor de AlunoSafoPreguicoso { super(nm, rl); //chamada ao construtor da classe-pai (Aluno ou sintaticamente "super") inteligencia = 1.0f; //todo objeto do tipo AlunoSafoPreguicoso tem inteligencia 1 } //ao ser criado //funções que fazem o override das abstratas definidas em Aluno public float getInteligencia() //retorna o valor de inteligencia { return inteligencia; } public float getDedicacao() //gera uma dediação randômica para o objeto da classe AlunoSafoPreguicoso { Random generator = new Random(); float r = generator.nextFloat(); return r*0.5f; //numeros em ponto flutuante sao tratados como double por default //portanto, para evitar inconsistência de tipos, o f final indica //que se trata de um float } }
3) Classe AlunoEsforcado
//de maneira análoga ao AlunoSafoPreguicoso, a classe AlunoEsforcado //herda todos os atributos e métodos de Aluno public class AlunoEsforcado extends Aluno { private float inteligencia; private float dedicacao; public AlunoEsforcado(String nm, RelaQueue rl) //construtor da classe { super(nm,rl); //construtor da classe-pai //todos os alunos do tipo AlunoEsforcado têm //atributos fixos. Eles poderiam ter sido inicializados //com atribuição direta no campo private. inteligencia = 0.5f; dedicacao = 1.0f; } //override das funções abstratas definidas na classe Aluno public float getInteligencia() //retorna inteligencia { return inteligencia; } public float getDedicacao() //retorna dedicacao { return dedicacao; } }
4) Classe Professor
import java.util.*; //a classe Professor será a classe que representará os efeitos //do professor retirando um relatório da fila (que é um atributo seu), //gerando uma nota com base nos atributos do aluno dono do relatório //mais um fator aleatório, (que aqui foi implementado como método público, //embora somente o método corrigirRelatorio precise utilizá-la) e imprimindo //o resultado da nota dos alunos public class Professor { private RelaQueue queueRela; public Professor(RelaQueue rel) //construtor da classse Professor { queueRela = new RelaQueue(); //cria fila... queueRela = rel; //e copia o conteúdo de rel, //passado como parâmetro quando da criação //de um objeto do tipo Professor } private float corrigirRelatorio(Relatorio rela) //atribuição das notas com base nas caracteristicas //dos relatorios e um fator aleatório caracteristico //da classe Professor { float nota = (rela.getQualidade() + rela.getOriginalidade() + fatorAleatorio() ) / 3 * 10; return nota; } public float fatorAleatorio() //gera um float entre 0 e 1 { Random generator = new Random(); float r = generator.nextFloat(); return r; } public void corrigirRelatorios() //retira relatórios da fila, corrige e exibe as notas { Relatorio aux; while((aux = queueRela.dequeue()) != null) System.out.println(aux.getAluno().getNome() + " : " + corrigirRelatorio(aux)); } }
5) Classe Relatorio
//a classe Relatorio contém os atributos de qualidade e originalidade //que serão criados no método fazEEntregaRelatorio() em Aluno, //além do próprio aluno que é dono do relatório public class Relatorio { private float qualidade; private float originalidade; private Aluno aluno; public Relatorio(float qual, float origin, Aluno al) //construtor de Relatorio //al será "this" em aluno //pois trata-se de uma auto-referência { qualidade = qual; originalidade = origin; aluno = al; } public float getQualidade() //retorna qualidade { return qualidade; } public float getOriginalidade() //retorna originalidade { return originalidade; } public Aluno getAluno() //retorna o aluno dono do relatório //método importante para sabero nome do aluno //através do relatório, chamando métodos aninhados { //esquematicamente: rela->getAluno->getNome return aluno; } }
6) Classe RelaQueue
//a classe que modela o TAD fila public class RelaQueue { //contem os campos inicio, fim e um vetor de objetos do tipo Relatorio private int inicio; private int fim; private Relatorio[] relaArray; public RelaQueue() //construtor { //a fila está vazia inicialmente inicio = 0; fim = 0; relaArray = new Relatorio[10]; //são alocados dez espaços para relaArray //isso significa que uma fila comporta //no máximo dez relatórios //é importante notar que inicialmente todas as entradas //no vetor relaArray apontam para null. //quando ocorre o "dequeue()", as entradas continuam //apontando para objetos do tipo Relatorio. //isso significa que qualquer método que utilize um teste //de fila vazia com null, limita o uso da fila a uma única vez // (como é o caso desta implementação) } public boolean isEmpty() //verifica se a fila está vazia { if(inicio == fim) return true; else return false; } public void queue(Relatorio rela) //enfileira um relatorio { relaArray[fim] = rela; //poe o objeto no fim fim = (fim + 1) % 10; //e anda mais uma posição } public Relatorio dequeue() //retira relatório da fila { if(isEmpty()) //se estiver vazia, retorne null //assim, o professor poderá saber //que não há mais relatórios na fila return null; else //senão retire normalmente { Relatorio tmp = relaArray[inicio]; inicio = (inicio + 1) % 10; return tmp; } }
O diagrama simplificado fica então:

Testando a aplicação
Utilizando o Code Pad
Uma das principais funcionalidades do BlueJ refere-se à possibilidade de se criar objetos de classes e "vê-los" se relacionando uns com os outros. Para tanto, basta clicar, com o botão direito do mouse, o quadro representativo da classe no diagrama simplificado que os métodos públicos (inclusive os herdados) da classe em questão aparecerão ao lado do quadro . Como exemplo, foram criados quatro objetos: um objeto rela do tipo RelaQueue, um objeto prof do tipo Professor, um objeto aluno1 do tipo AlunoEsforcado e um objeto aluno2 do tipo AlunoSafoPreguicoso.

O objeto aluno1, por exemplo, vai se chamar John Smith e sua fila será, obviamente, o objeto rela. Esses dois parâmetros são passados ao construtor da classe AlunoEsforcado, que por sua vez irá passar o parâmetro John Smith para o construtor da classe-pai.

Após a criação dos objetos, observa-se que a fila está vazia inicialmente. Isto está claro pelo valor que o método isEmpty(), da classe RelaQueue retorna , isto é, true.

Em seguida, o aluno1 irá chamar o método fazEEntregaRelatorio(), que ele herdou da classe Aluno (que em Java é traduzido pela palavra-chave extends). Desse modo, o objeto aluno1 cria um objeto do tipo Relatório e repassa para rela para enfileirar seu trabalho.

Nota-se que, de fato, a fila já não está mais vazia!

Portanto, o objeto prof pode agora retirar o relatório criado por aluno1 da fila, corrigir…

…e exibir sua nota.

Utilizando uma classe de teste
Utilizando a classe teste, cujo código-fonte pode ser encontrado na seção Testando a aplicação, do 1° laboratório, obtém-se os seguintes resultados:
A barra verde indica que a compilação do programa foi bem-sucedida.

Para testar a aplicação com a classe test, basta clicar com o botão direito do mouse no seu quadro representativo e escolher Test All.

As notas dos alunos aluno2, aluno3 e aluno4 aparecem no Terminal Window como conseqüência da correção dos relatórios. A nota do aluno1 não aparece pois, seu relatório sai da fila antes da correção:
... Relatorio rela1 = queue.dequeue(); ...

Conclusão
No primeiro laboratório, foram explorados diversas características de Orientção a Objetos, como herança e encapsulamento, onde foram utilizados os conceitos de extensão de classe e overriding de funções, que está diretamente ligado com polimorfismo. Além disso foi aprendido como a linguagem Java se relaciona com o conceito de Orientação a Objetos, observando suas palavras-chaves e sua sintaxe. Para quem não sabia nada sobre o assunto, um exercício relevante que certamente demandou estudo sobre a linguagem e os conceitos por trás dela.






Código OK e bom rela. Bons comentários. fatorAleatorio() poderia ser private.