Difference between revisions of "Classes Internas (Java)/Gatos Iteráveis"

From Wiki**3

< Classes Internas (Java)
(Leitura adicional)
(Caso 1: definição de duas classes independentes)
Line 9: Line 9:
  
 
== Caso 1: definição de duas classes independentes ==
 
== Caso 1: definição de duas classes independentes ==
 +
 +
Este exemplo apresenta o conceito de Gato como iterável, mas não disponibiliza nesse conceito nenhuma definição para o tipo do iterador. Esta situação implica que o iterador tem de ser definido depois da classe do gato estar terminada. Pode implicar ainda que a classe do gato tenha de disponibilizar uma interface pública para permitir a definição e funcionamento do iterador (sem a qual o iterador pode não ter acesso às estruturas internas do gato).
 +
 +
=== Classe do conceito gato: Cat ===
 +
 +
Os métodos '''size()''' e part(int i)''' são utilizados pelo iterador, mas expõem aspectos da implementação internada do gato.
 +
 +
Note-se que o método '''iterador()''', imposto pela interface '''Iterable<T>''', retorna a um iterador para a instância da classe do gato à qual é pedido o iterador. Como as intâncias das classes do iterador e do gato não têm nenhuma relação especial, é necessário informar o iterador sobre o gato a iterar.
 +
<java5>
 +
import java.util.List;
 +
import java.util.ArrayList;
 +
import java.util.Iterator;
 +
public class Cat implements Iterable<CatPart> {
 +
  private List<CatPart> _parts = new ArrayList<CatPart>();
 +
 +
  public Cat(int nparts) {
 +
    for (int i = 0; i < nparts; i++)
 +
      _parts.add(new CatPart(i));
 +
  }
 +
 +
  public int size() { return _parts.size(); }
 +
 +
  public CatPart part(int i) { return _parts.get(i); }
 +
 +
  public Iterator<CatPart> iterator() {
 +
    return new CatIterator(this);
 +
  }
 +
 +
}
 +
</jav5>
 +
 +
=== Classe do iterador: CatIterator ===
 +
 +
Esta classe implementa a interface '''Iterator<T>''', em que '''T''' é uma parte do gato. A interface obriga à implementação dos métodos '''hasNext()''', '''next()''' e '''remove()'''. Estas implementações são feitas com base no índice gerido pelo iterador e na intância de gato passada no construtor.
 +
 +
<java5>
 +
import java.util.Iterator;
 +
public class CatIterator implements Iterator<CatPart> {
 +
  Cat _cat;
 +
  int _index = 0;
 +
  public CatIterator(Cat cat) { _cat = cat; }
 +
  public boolean hasNext() { return _index < _cat.size(); }
 +
  public CatPart next() { return _cat.part(_index++); }
 +
  public void remove() { throw new UnsupportedOperationException(); }
 +
}
 +
</java5>
 +
 +
=== Classe de parte de gato: CatPart ===
 +
 +
Esta é uma classe muito simples que serve apenas para ilustrar a construção de um gato a partir de partes de gato. Neste exemplo, não é feita nenhuma distinção entre as várias partes (em exemplos mais elaborados, o polimorfismo de inclusão vai permitir continuar a ignorar as diferenças na maior parte, se não em todos, dos casos). O único método definido (além do construtor) é o método '''toString()''', para permitir obter alguma informação útil (distinguir as partes) quando se imprime um gato.
 +
 +
<java5>
 +
public class CatPart {
 +
  private int _i;
 +
  public CatPart(int i) { _i = i; }
 +
  public String toString() { return "PART #" + _i; }
 +
}
 +
</java5>
 +
 +
=== Aplicação exemplo ===
 +
 +
Esta aplicação ilustra a utilização dos conceitos acima. Note-se que o modo de iteração utilizado (''for-each'') é válido para entidades que implementem o conceito '''java.util.Iterable<T>''' e para arrays primitivos.
 +
 +
<java5>
 +
public class App {
 +
  public static void main(String[] args) {
 +
    Cat cat = new Cat(5);
 +
    for (CatPart part: cat)
 +
      System.out.println(part);
 +
  }
 +
}
 +
</java5>
 +
 +
== Como Executar ==
 +
 +
O processo de execução é o habitual. Primeiro, é necessário compilar as classes:
 +
 +
javac App.java CatIterator.java Cat.java CatPart.java
 +
 +
Em segundo lugar, executa-se a partir da classe que contém o método '''main()''':
 +
 +
java App
 +
 +
O resultado é:
 +
 +
<text>
 +
PART #0
 +
PART #1
 +
PART #2
 +
PART #3
 +
PART #4
 +
</text>
 +
 +
[[category:PO]]
 +
[[category:Ensino]]
 +
[[category:PO Exemplos]]
  
 
== Caso 2: reutilização de iteradores ==
 
== Caso 2: reutilização de iteradores ==

Revision as of 15:32, 21 October 2013

A tarefa nestes exemplos é definir um gato iterável.

Iterar implica a capacidade de obter múltiplas entidades a partir de um gato. Embora seja perfeitamente possível definir iteradores independentes da linguagem Java, é mais conveniente usar os conceitos Java para iteração, pois permitem utilizar algoritmos pré-definidos para iteradores (tirando partido do polimosfismo) e utilizar a sintaxe especial for-each, aplicável a entidades iteráveis e arrays (i.e., entidade primitivas com dimensão fixa).

Assim, serão implementadas duas interfaces pré-definidas em Java. A primeira das interfaces é java.lang.Iterable<T> e é implementada pelas classes que representam, em cada caso, o conceito de gato. Em geral, esta interface é implementada por qualquer entidade que representa um qualquer tipo de colecção de objectos.

A segunda interface é java.util.Iterator<T> e é implementada pelos iteradores definidos para as entidades iteráveis. Note-se que alguns dos exemplos de implementação serão internos, embora esta interface seja exterior a todas as classes.

Caso 1: definição de duas classes independentes

Este exemplo apresenta o conceito de Gato como iterável, mas não disponibiliza nesse conceito nenhuma definição para o tipo do iterador. Esta situação implica que o iterador tem de ser definido depois da classe do gato estar terminada. Pode implicar ainda que a classe do gato tenha de disponibilizar uma interface pública para permitir a definição e funcionamento do iterador (sem a qual o iterador pode não ter acesso às estruturas internas do gato).

Classe do conceito gato: Cat

Os métodos size() e part(int i) são utilizados pelo iterador, mas expõem aspectos da implementação internada do gato.

Note-se que o método iterador(), imposto pela interface Iterable<T>, retorna a um iterador para a instância da classe do gato à qual é pedido o iterador. Como as intâncias das classes do iterador e do gato não têm nenhuma relação especial, é necessário informar o iterador sobre o gato a iterar. <java5> import java.util.List; import java.util.ArrayList; import java.util.Iterator; public class Cat implements Iterable<CatPart> {

 private List<CatPart> _parts = new ArrayList<CatPart>();
 public Cat(int nparts) {
   for (int i = 0; i < nparts; i++)
     _parts.add(new CatPart(i));
 }
 public int size() { return _parts.size(); }
 public CatPart part(int i) { return _parts.get(i); }
 public Iterator<CatPart> iterator() {
   return new CatIterator(this);
 }

} </jav5>

Classe do iterador: CatIterator

Esta classe implementa a interface Iterator<T>, em que T é uma parte do gato. A interface obriga à implementação dos métodos hasNext(), next() e remove(). Estas implementações são feitas com base no índice gerido pelo iterador e na intância de gato passada no construtor.

<java5> import java.util.Iterator; public class CatIterator implements Iterator<CatPart> {

 Cat _cat;
 int _index = 0;
 public CatIterator(Cat cat) { _cat = cat; }
 public boolean hasNext() { return _index < _cat.size(); }
 public CatPart next() { return _cat.part(_index++); }
 public void remove() { throw new UnsupportedOperationException(); }

} </java5>

Classe de parte de gato: CatPart

Esta é uma classe muito simples que serve apenas para ilustrar a construção de um gato a partir de partes de gato. Neste exemplo, não é feita nenhuma distinção entre as várias partes (em exemplos mais elaborados, o polimorfismo de inclusão vai permitir continuar a ignorar as diferenças na maior parte, se não em todos, dos casos). O único método definido (além do construtor) é o método toString(), para permitir obter alguma informação útil (distinguir as partes) quando se imprime um gato.

<java5> public class CatPart {

 private int _i;
 public CatPart(int i) { _i = i; }
 public String toString() { return "PART #" + _i; }

} </java5>

Aplicação exemplo

Esta aplicação ilustra a utilização dos conceitos acima. Note-se que o modo de iteração utilizado (for-each) é válido para entidades que implementem o conceito java.util.Iterable<T> e para arrays primitivos.

<java5> public class App {

 public static void main(String[] args) {
   Cat cat = new Cat(5);
   for (CatPart part: cat)
     System.out.println(part);
 }

} </java5>

Como Executar

O processo de execução é o habitual. Primeiro, é necessário compilar as classes:

javac App.java CatIterator.java Cat.java CatPart.java

Em segundo lugar, executa-se a partir da classe que contém o método main():

java App

O resultado é:

<text> PART #0 PART #1 PART #2 PART #3 PART #4 </text>

Caso 2: reutilização de iteradores

Caso 3: usando classes internas

Caso 4: usando classe interna a um método

Caso 5: usando classe anónima

Caso 6: usando classes anónimas e polimorfismo

Leitura adicional

Ver o manual de Java, para os conceitos acima.