Lab1 Thiago Brandão

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:

figura1.png

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.

figura2.png

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.

figura11.png

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.

figura3.png

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.

figura4.png

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

figura5.png

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

figura6.png

…e exibir sua nota.

figura7.png

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.

figura8.png

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.

figura10.png

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();
...
figura9.png

Download do projeto completo

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.

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License