Tópicos de Poo e Java

Neste módulo veremos:

Membros static de classes

Sabemos que cada objeto tem uma cópia de todas as variáveis da classe instanciada. No entanto, existem casos em que queremos que todos os objetos compartilhem sómente uma cópia da variável de classe. Para estes casos usa-se o rótulo static. Dizemos assim que uma variável de classe static tem escopo de classe, ou seja, é conhecida por todos os objetos instanciados dela, ou ainda, todos os objetos compartilham o mesmo dado.

Variáveis de classe static não são variáveis globais, mesmo que elas sejam declaradas como public static.

Vejamos alguns exemplos de métodos static:

Vejamos alguns exemplos de variáveis static:

Reparem que o acesso aos métodos e às variáveis deve ser sempre feito via sua classe. Veja os vários exemplos em Math e em java.lang nas páginas da API.

Analisem a classe abaixo e proponham um código Java para testá-la.

/** Acme.java
 */

public class Acme {
  private static int num;
  private String nome;
  
  public Acme(String nome)
  {
    this.nome = nome;
    num++;
  }

  public int getQuantos()
  {
	return num;
  }
  
  public String toString() 
  {
	return("["+nome+": de "+num+"]");
  }
}

Finalizadores

Uma das atribuições dos construtores é buscar no sistema recursos de memória através do operador new. Os recursos de memória podem ser considerados como dos recuros mais importantes para a continuidade e a manutenção dos objetos no sistema.

Java proporciona uma coleta de lixo automática de memória que é usada para devolver ao sistema recursos de memória de objetos que não estão mais em uso.

É importante saber que em Java não existe um método como delete() que pode ser explicitamente chamado para a remoção de recursos de memória do sistema, como por exemplo, tem em outras linguagens. C tem o free() e C++ tem seus destrutores ~.

Os objetos para os quais não existem mais referências são marcados para a coleta de lixo. Quando o coletor de lixo é chamado os recursos usados por estes objetos são devolvidos ao sistema. Veja o código abaixo:

  void metodo()
  {
    cadeia = new String();
  }

Neste código cadeia pode ser considerada uma referência lixo assim que o método terminar sua execução. Esta referência estará pronta para ser coletada pelo coletor de lixo. A memória usada por este objeto poderá ser recuperada.

A maneira mais simples de assegurar da possibilidade de um objeto ser resgatado pelo coletor de lixo é fazer a referência para ele ser null. Isso pode ser a atribuição do método finalize

No entanto, o conceito do coletor de lixo em Java é sempre superestimado, ou seja, atribui-se a ele tarefas que ele realmente não necessita ou não são suportados pela definição da linguagem.

Só há duas situações especificadas para a atuação do coletor de lixo:

e isso é só.

Cada classe Java pode ter um método finalizador para retornar recursos ao sistema. É garantido que o finalizador é chamado para executar a sua tarefa de limpeza antes do coletor de lixo atuar.

Observações

Adicione o método abaixo na classe Acme e execute o código seguinte para testar o método finalizador.

  public void finalize()
  {
    System.out.println(this.nome+" e seu finalize().");
    num--;
  }

Agora o código para testar o finalizador:

/** TAcme.java
 */
 
public class TAcme {
  public static void main (String[] xyz) {
	  Acme a1, a2, a3;
	  
	  a1 = new Acme("cadeira");
	  a2 = new Acme("sol");
	  a3 = new Acme("deputado");
	  
	  System.out.println(a1 +""+ a2 +""+ a3);
	  a3.finalize();
	  System.out.println(a1);
	  System.gc();
	  System.out.println(a3);
  }
}

Abaixo está a saída deste código:

[cadeira: de 3][sol: de 3][deputado: de 3]
deputado e seu finalize().
[cadeira: de 2]
[deputado: de 2]

Reparem que o método finalizador não destruiu o objeto a3. A referência continua existindo. Não é uma boa idéia chamar o coletor de lixo explicitamente e mesmo assim, com o método finalize() não há maneiras de limpar apontadores para arquivos, streams em geral. A melhor maneira de liberar recursos ainda é contar com o coletor de lixo, apontando os objetos para null quando não forem mais utilizados e fechando outros recursos com o método close() Veja o exemplo no código abaixo. Ele usa recursos um pouco mais avançados mas este é o preço da tarefa bem feita.

/**
 * modificado de JDC Tech Tips: January 24, 2000
 * http://java.sun.com/developer/TechTips/2000/tt0124.html
 */
public class Finalize1 {
  private static final int iteracao = 100;
                
  static public void main(String[] args) {
    int n;
    // inicializa um conjunto de objetos que usam finalize()
    for (n = 0; n < iteracao; n++) {
      UsesFinalize uf = new UsesFinalize();
    }

    // inicializa um conjunto de objetos que usa close()
    // para a *limpeza* de recursos. Um pouco mais complexo
    // que o anterior
    for (n = 0; n < iteracao; n++) {
      UsesClose uf = null; 
      try {
        uf = new UsesClose();
      }
      finally {
        if (uf != null)
          uf.close();
        }
    }
    System.out.println("Este demonstrativo mostra o perigo de confiar"+
      " no finalize() para encerrar os recursos utilizados.");
    System.out.println("Teste para "+iteracao+" objetos:");
    System.out.println("Uso do finalize() para encerrar recursos: " 
      + UsesFinalize.maxActive + " recursos ainda abertos.");   
    System.out.println("Usando close() explicitamente " 
    + UsesClose.maxActive + " recursos ainda abertos.");     
  }
        
  static public class UsesFinalize {
    static int active;
    static int maxActive;
                
    UsesFinalize() {
      active++;
      maxActive = Math.max(active, maxActive);
    }
                
    public void finalize() {
      active--;
    }
  }// UsesFinalize
        
  static public class UsesClose {
    static int active;
    static int maxActive;
                
    public UsesClose() {
      active++;
      maxActive = Math.max(active, maxActive);
    }
                
    public void close() {
      active--;
    }
  }
}//Finalize1
Mais detalhes

TechTips de 2000
TechTips de 2003.

Métodos e classes final

As variáveis de classe do tipo final não podem ser modificadas depois de serem declaradas. As variáveis deste tipo devem ser sempre inicializadas. Mais:

Observações

As classes String, Boolean e Byte, entre outras, são exemplos de classes final.

Exercício

Crie uma classe Mecanica que contenha uma variável static final g=9,8 e que seja usada para calcular o tempo de queda-livre segundo a fórmula t = ((2*h)/g)^(1/2).

Classes abstratas e classes concretas

As classes abstratas são classes que não podem ser instanciadas para a ciração de um objeto.
A maior utilidade destas classes está na previsão de criação de classes herdeiras que especializam as classes abstratas.

As classes as quais objetos podem ser instanciados são chamadas de classes concretas.

Imaginemos uma instituição em qoe todos os seus usuários e trabalhadores são categorizados, como por exemplo, num hospital. Podemos usar superclasses abstratas como topo da herança dos usuários e trabalhadores do hospital e, classes concretas com as características específicas para cada objeto a ser originado delas. Vejam o exemplo:

Outro exemplo:

Pode haver herança em classes abstratas, só não pode haver instanciação.

As superclasses abstratas são usadas para a criação de interfaces (padronização) de programação, ou seja, para o estabelecimento de um conjunto de métodos com o mesmo nome tanto para a superclasse como para as subclasses, nomes este que devem ser utilizados não importa qual o objeto.

Aqui os conceitos de abstração e polimorfismo se completam de maneira a fundamentar os principais marcos de POO, junto com o conceito de herança.

Exercício

Criar uma classe abstrata Forma com os métodos padrão de área e volume e as subclasses Ponto e Circulo desta classe Forma. Veja o modelo abaixo.

public abstract class Forma {
...
}

public class Ponto extends Forma{
  protected x, y;
...
}

public class Circle extends Point {
  protected double raio;
...
}
Última modificação feita em: 13 de setembro de 2006
Evandro Eduardo Seron Ruiz, PhD (evandro at usp ponto br)
www.imagcom.org/evandro/ibm1030