Métodos e atributos de classe na prática

Aula de Laboratório

(adaptada da aula da profa. Isabel Manssour e do prof. Marcelo Cohen)

Objetivos:

Criar e utilizar atributos e métodos de classe

Abra o Eclipse e crie um novo projeto para esta aula.

Sugerimos agora a criação da classe Relogio apresentada na listagem abaixo.

 
/**
  * Classe Relogio.
  * 
  * @author Autor 
  * @version agosto/2006
  */
 
import java.text.DecimalFormat;
 
public class Relogio
{
   // Atributos
   private int hora, minuto, segundo;
 
   /**
     * Construtor para objetos da classe relógio
     * @param int h (hora), int m (minuto), int s (segundo)
     */
   public Relogio(int h, int m, int s)
   {
      acertaHora(h,m,s); 
   }
 
   /**
     * Construtor para objetos da classe relógio
     * @param int h (hora), int m (minuto)
     */
   public Relogio(int h, int m)
   {
      acertaHora(h,m,0); 
   }
 
   /**
     * Construtor para objetos da classe relógio
     * @param int h (hora)
     */
   public Relogio(int h)
   {
      acertaHora(h,0,0); 
   }
 
   /**
     * Método para incrementar um segundo
     */ 
   public void incrementa()
   {
     if(++segundo>59)
     {
        segundo = 0;
        if(++minuto>59)
        {
          minuto = 0;
          if(++hora>23)
            hora = 0;
        }
     }
   }
 
   /**
     * Método para decrementar um segundo
     */ 
   public void decrementa()
   {
     if(--segundo<0)
     {
        segundo = 59;
        if(--minuto<0)
        {
          minuto = 59;
          if(--hora<0)
            hora = 23;
        }
     }
   }
 
   /**
     * Método para atualizar a hora atual
     * @param int h (hora), int m (minuto), int s (segundo)
     */ 
   public void acertaHora(int h, int m, int s)
   {
      if (h >= 0 && h <= 23)
        hora = h;
      else 
        hora = 0;
      if (m >= 0 && m <= 59)
        minuto = m;
      else 
        minuto = 0;      
      if (s >= 0 && s <= 59)
        segundo = s;
      else 
        segundo = 0;  
   } 
 
   /**
     * Método para informar a hora atual
     * @return String hora
     */ 
   public String toString()
   {
      DecimalFormat numInt = new DecimalFormat("00"); 
      String str = "Hora atual:" +numInt.format(hora)+":"+numInt.format(minuto)+":"+numInt.format(segundo);
      return str;
   }
}


Para que seja possível testar a criação de instâncias das classes Relogio, acrescente a classe abaixo no seu projeto. Depois, complete o código conforme especificado.

 
/**
 * Classe CriaInstancias.
 * 
 * @author Autor
 * @version agosto/2006
 */
 
public class CriaInstancias
{
    /**
     * Método main
     */
    public static void main(String args[])
    {
       Relogio r1, r2, r3;
       // Instancie três objetos relógio
       // Apresente os valores dos atributos de cada um dos objetos através da chamada do método toString()
    }
}


 

1. Métodos de classe e de instância

Como já estudado, métodos de instância são aqueles que estão disponíveis apenas quando existe uma instância, pois manipulam os atributos contidos nesta instância. Então, todos os métodos que escrevemos até agora são de instância.

Mas, imagine que queremos estender a classe Relogio, permitindo que ela seja capaz de calcular e retornar a diferença entre duas horas:

public class Relogio
{
   ...
  /**
   * Método para calcular a diferença em segundos entre duas horas
   */ 
   public int difHora(int h1,int m1,int s1,int h2,int m2,int s2)
   {
      int dif;
      // Calculos
      ...
      return dif;
   } 

Olhando com atenção, notamos que esse método não utiliza nenhum atributo da instância (hora, minuto ou segundo). Então, teoricamente ele poderia ser utilizado independentemente da existência ou não de instâncias, certo? Para tanto, declara-se o método como static, indicando que é um método de classe, ou seja, não depende de nenhum atributo de instância:

public class Relogio
{
   ...
  /**
   * Método para calcular a diferença em segundos entre duas horas
   */ 
   public static int difHora(int h1,int m1,int s1,int h2,int m2,int s2)
   {
      int dif;
      // Calculos (invente alguma coisa)
      ...
      return dif;
   }

Copie e complete o código acima.

Para utilizar o método de classe em qualquer parte de um programa Java, utilize a sintaxe abaixo, ou seja, NomeDaClasse.metodo(..)
 

   ...
   public static void main(String args)
   {
      ...
      int dif;
      dif = Relogio.difHora(15,10,5,20,10,2);
      System.out.println("A diferença entre as duas horas é: "+dif);
      ...
   } 

Se você prestar atenção, verá que já usava um método de classe sem saber: System.out.println(...) é uma chamada para o método println(...), dentro do objeto out, presente na classe System (funções gerais do sistema).

2. Atributos de classe e de instância

Todos os atributos que usamos até agora são atributos de instância, ou seja, existe uma cópia de cada atributo em cada instância que criamos. Cada um pode armazenar um valor diferente, dependendo da instância. Porém, assim como existem métodos de classe, também existem atributos de classe. Para que serviria um atributos de classe?

Não seria ótimo se cada instância da classe Relogio soubesse quantas outras existem?

A melhor maneira de fazer isso é declarar um atributo de classe (static) para armazenar a quantidade de instâncias já criadas.

E como fazer isso?

Simples, inicializamos este atributo com zero (na declaração) e no construtor incrementamos esse valor. Como é um atributo de classe, quando o utilizarmos em diversas instâncias, na verdade estaremos atualizando o mesmo atributo:

public class Relogio
{
   private int hora, minuto, segundo;
   private static int total = 0; // quantidade de relogios
 
   // Construtores
   public Relogio(int h,int m,int s)
   {
      total++;
      acertaHora(h,m,s);
   }
   ... // incremente o atributo “total” nos demais construtores

Para verificar o seu funcionamento, crie vários objetos relógios e inspecione o conteúdo dos atributos de qualquer um deles.

Repare que o atributo total aparece separado, pois é um static field, ou seja, um atributo de classe. Atributos de classe também são comumente utilizados para armazenar constantes úteis ao programa inteiro, por exemplo, armazenar a quantidade de horas em um dia:

public class Relógio
{
   private int hora, minuto, segundo;
   private static int total = 0; // qtd. de relogios
   public static final int HORAS_DIA = 24;
   ...

Lembre-se que constantes são declaradas com o modificador final.

Quando queremos que uma constante possa ser utilizada por outras classes (como no exemplo acima), devemos declará-la como public. Caso contrário, só será possível utilizá-la nesta classe.
 

Exercício:

  • Inclua um método na classe Relogio para retornar a quantidade de relógios que já foram criados. Esse método pode ou deve ser static? Quais as implicações disso? 
  • Acrescente à classe Ponto, desenvolvida anteriormente em sala de aula, a capacidade de calcular a distância entre dois pontos recebidos como argumento, sabendo que a fórmula é a seguinte:
    Obs.: Lembre-se: iniciamos a fazer este exercício em sala de aula.
  • Crie uma classe Funcionario que contém como atributos código, nome, endereço e CPF. O código dos funcionários deve ser criado automaticamente pelo programa. Assim, é necessário ter um atributo de classe que irá conter o código do próximo funcionário, além de um atributo de instância que deverá conter o código de cada funcionário. Depois, implemente uma classe Cadastro que possua um ArrayList de funcionários e métodos para incluir, excluir e consultar dados de funcionários. Teste a utilização destas classes criando uma classe que implemente o método main e crie um cadastro de funcionários.


 

Não deixe o laboratório se houver alguma dúvida com relação a:

  • criação e utilização de atributos e métodos de classe