Interfaces
Listas e listas ligadas
Iteradores
 Polimorfismo de subtipos
 Classes e operações polimórficas
 Herança
 Ligação estática e ligação dinâmica
 Classes abstractas e classes concretas
 Operações abstractas
 Análise, desenho e implementação
 Dicionário do domínio
 Conceitos
 Conceitos concretos e conceitos abstractos
2013/2014 Fundamentos de Programação 2
 Definem um comportamento que as classes podem
implementar
 Contêm apenas constantes e declarações de
operações (e tipos embutidos)
 Classes podem implementar interfaces
 Uma classe pode implementar várias interfaces,
embora possa derivar apenas de uma outra classe
 Uma interface pode estender (derivar de) outra
2013/2014 Fundamentos de Programação 3
public interface Comparable<Type> {
int compareTo(Type object);
}
public interface Queue<Item> {
Item element();
void add(Item item);
void remove();
}
2013/2014 Fundamentos de Programação 4
Operações apenas declaradas.
Não se define qualquer método.
Não é necessário usar o
qualificador abstract.
Operações públicas
por omissão.
Nota: A interface Queue é um
pouco diferente na biblioteca do
Java!
Interface genérica. Type é um
parâmetro. O correspondente
argumento tem de ser um tipo.
public final class Rational implements Comparable<Rational> {
private final int numerator;
private final int denominator;
…
@Override
public int compareTo(final Rational another) {
final int leftNumerator =
getNumerator() * another.getDenominator();
final int rightNumerator =
another.getNumerator() * getDenominator();
if (leftNumerator > rightNumerator)
return 1;
if (leftNumerator < rightNumerator)
return -1;
return 0;
}
…
}
2013/2014 Fundamentos de Programação 5
public final class Rational implements Comparable<Rational> {
private final int numerator;
private final int denominator;
…
public int compareTo(final Rational another){
…
}
…
}
Implementação
2013/2014 Fundamentos de Programação 6
«interface»
Comparable<Type → Rational>
Rational
Relação de
realização
Comparable<Type → Rational>
Rational
public class CustomerQueue implements Queue<Customer> {
…
}
public class MyQueueTester {
…
public static void main(final String[] arguments) {
Queue<Customer> customerQueue =
new CustomerQueue();
…
}
…
}
2013/2014 Fundamentos de Programação 7
Queue<Item → Customer>
CustomerQueue
 Adjectivo denotando possibilidade de realizar
determinadas operações (e.g., Comparable)
 Nome denotando conceito cujo
comportamento será implementado (e.g.,
Queue)
2013/2014 Fundamentos de Programação 8
Caso semelhante ao das classes abstractas, mas
1. não há qualquer herança de implementação (i.e.,
de atributos não constantes e métodos) e
2. uma classe que implemente a interface pode
simultaneamente implementar outras interfaces.
 Precisa-se de classes semelhantes
 Com operações semelhantes
 Com atributos semelhantes
 Variando apenas em alguns tipos (e.g., o tipo dos
elementos a guardar em diferentes listas)
 É necessário definir essas classes
separadamente?
2013/2014 Fundamentos de Programação 9
public class ArrayList {
private Object[] items;
…
}
2013/2014 Fundamentos de Programação 10
- items
*
ObjectArrayList
Room
public class ArrayList<Item> {
private Item[] items;
…
}
2013/2014 Fundamentos de Programação 11
ArrayList<Item → Room> Room
*
- items
ArrayList
Item
«bind» <Item → Room>
- items : Item [*]
Notação UML para classes
genéricas (também conhecidas
por modelos ou templates).
Classe genérica. Item é um
parâmetro. O correspondente
argumento tem de ser um tipo.
public class Floor {
private ArrayList<Room> rooms =
new ArrayList<Room>();
public Floor(final int numberOfRooms) {
for (int roomNumber = 1;
roomNumber != numberOfRooms + 1;
roomNumber++)
rooms.addFirst(new Room(roomNumber));
}
public void show() {
while (rooms.hasNext())
out.println(rooms.next());
}
}
2013/2014 Fundamentos de Programação 12
Inserir novo elemento no início ou a meio
da lista implica «empurrar» elementos
existentes para «fazer espaço».
Para fazer isto o
que é preciso?
public class LinkedList<Item> {
private Node<Item> firstNode = null;
private Node<Item> currentNode = null;
…
private static class Node<Item> {
private Node<Item> nextNode;
private Item item;
private Node(final Node<Item> nextNode,
final Item item) {
this.nextNode = nextNode;
this.item = item;
}
}
…
}
2013/2014 Fundamentos de Programação 13
Classe embutida (nested)
privada. A classe
LinkedList<Item> tem
acesso aos membros
privados de Node<Item>.
2013/2014 Fundamentos de Programação 14
LinkedList
Item
Node
Item
- nextNode: Node
- item: Item
LinkedList
Item
- firstNode: Node<Item>
- currentNode: Node<Item>
Node
Item
- nextNode: Node
- item: Item
Notações para o
embutimento.
LinkedList::Node
Item
- nextNode: Node
- item: Item
LinkedList
Item
- firstNode: Node<Item>
- currentNode: Node<Item>
public class Floor {
private LinkedList<Room> rooms =
new LinkedList<Room>();
public Floor(final int numberOfRooms) {
for (int roomNumber = 1;
roomNumber != numberOfRooms + 1;
roomNumber++)
rooms.addFirst(new Room(roomNumber));
}
public void show() {
while (rooms.hasNext())
out.println(rooms.next());
}
}
2013/2014 Fundamentos de Programação 15
Inserir novo elemento no início ou no meio
da lista não implica «empurrar» elementos
existentes!
2013/2014 Fundamentos de Programação 16
rooms : LinkedList<Item → Room>
: Node<Item → Room>
firstNode currentNode
nextNode
item item
nextNode = null
: Room
: Node<Item → Room>
: Room
public class LinkedList<Item> {
private Node<Item> firstNode = null;
…
private static class Node<Item> {
…
private Node(final Node<Item> nextNode,
final Item item) {
this.nextNode = nextNode;
this.item = item;
}
}
public void addFirst(final Item newItem) {
firstNode = new Node<Item>(firstNode, newItem);
}
…
}
2013/2014 Fundamentos de Programação 17
2013/2014 Fundamentos de Programação 18
rooms : LinkedList<Item → Room>
: Node<Item → Room>
firstNode currentNode
nextNode
item item
nextNode = null
: Room
: Node<Item → Room>
: RoomnewItem : Room
: Node<Item → Room>
nextNode
item
firstNode
public class LinkedList<Item> {
…
public void removeFirst() {
if (isEmpty())
throw new NoSuchElementException(…);
if (currentNode == firstNode)
currentNode = currentNode.nextNode;
Node<Item> nextFirstNode = firstNode.nextNode;
firstNode.item = null;
firstNode.nextNode = null;
firstNode = nextFirstNode;
}
…
}
2013/2014 Fundamentos de Programação 19
2013/2014 Fundamentos de Programação 20
rooms : LinkedList<Item → Room>
: Node<Item → Room>
firstNode currentNode
nextNode
item item
nextNode = null
: Room
: Node<Item → Room>
: Room
item = null
nextFirstNode : «ref» Node<Item → Room>
firstNode
public class LinkedList<Item> {
…
public void addLast(final Item newItem) {
if (firstNode == null)
firstNode = new Node<Item>(null, newItem);
else
lastNode().nextNode = new Node<Item>(null, newItem);
}
private Node<Item> lastNode() {
Node<Item> node = firstNode;
while (node.nextNode != null)
node = node.nextNode;
return node;
}
…
}
2013/2014 Fundamentos de Programação 21
public class LinkedList<Item> {
…
public void addLast(final Item newItem) {
if (firstNode == null)
firstNode = new Node<Item>(null, newItem);
else {
Node<Item> lastNode = firstNode;
while (lastNode.nextNode != null)
lastNode = lastNode.nextNode;
lastNode.nextNode = new Node<Item>(null, newItem);
}
}
…
}
2013/2014 Fundamentos de Programação 22
2013/2014 Fundamentos de Programação 23
rooms : LinkedList<Item → Room>
: Node<Item → Room>
firstNode currentNode
nextNode
item item
nextNode = null
: Room
: Node<Item → Room>
: Room
lastNode : «ref» Node<Item → Room>
nextNode = null
: Node<Item → Room>
nextNode
newItem : Room
item
public class LinkedList<Item> {
…
public Item next() {
if (!hasNext())
throw new NoSuchElementException("…");
if (currentNode == null)
currentNode = firstNode;
else
currentNode = currentNode.nextNode;
return currentNode.item;
}
…
}
2013/2014 Fundamentos de Programação 24
2013/2014 Fundamentos de Programação 25
rooms : LinkedList<Item → Room>
: Node<Item → Room>
firstNode currentNode
nextNode
item item
: Room
: Node<Item → Room>
: Room
nextNode = null
: Node<Item → Room>
nextNode
item
currentNode
: Room
2013/2014 Fundamentos de Programação 26
LinkedList
Item
Node
Ite
m
- item: Item
nextNode
firstNode
currentNode 0..1
0..1
0..1
0..1
Esta solução não
permite percorrer a
lista mais do que uma
vez em paralelo!
0..1
0..1
1
*
public class Floor {
private LinkedList<Room> rooms =
new LinkedList<Room>();
public Floor(final int numberOfRooms) {
for (int roomNumber = 1;
roomNumber != numberOfRooms + 1;
roomNumber++)
rooms.add(new Room(roomNumber));
}
public void show() {
while (rooms.hasNext())
out.println(rooms.next());
}
}
2013/2014 Fundamentos de Programação 27
public class Floor {
private LinkedList<Room> rooms =
new LinkedList<Room>();
public Floor(final int numberOfRooms) {
for (int roomNumber = 1;
roomNumber != numberOfRooms + 1;
roomNumber++)
rooms.add(new Room(roomNumber));
}
public void show() {
LinkedList<Room>.Iterator i = rooms.iterator();
while(i.hasNext())
out.println(i.next());
}
}
2013/2014 Fundamentos de Programação 28
public class Floor {
private LinkedList<Room> rooms =
new LinkedList<Room>();
public Floor(final int numberOfRooms) {
for (int roomNumber = 1;
roomNumber != numberOfRooms + 1;
roomNumber++)
rooms.add(new Room(roomNumber));
}
public void show() {
Iterator<Room> i = rooms.iterator();
while(i.hasNext())
out.println(i.next());
}
}
2013/2014 Fundamentos de Programação 29
Iterator é uma
classe interna (inner).
As suas instâncias têm
uma ligação implícita
à instância da classe
envolvente que as
criou. A ver com
pormenor mais tarde.
2013/2014 Fundamentos de Programação 30
LinkedList
Item
Node
Item
- item: Item
nextNode
firstNode currentNode
0..10..1
0..1
Esta solução permite
percorrer a lista mais
do que uma vez em
paralelo!
Iterator
LinkedList.this
*
0..1
0..1
*
*
1
 Permitem iterar ao longo de uma sequência de
elementos, actuando sobre essa sequência
 A uma sequência podem associar-se vários
iteradores
 Classes que forneçam iteradores podem ser
usadas em ciclos for-each…
 … mas têm de implementar a interface Iterable
2013/2014 Fundamentos de Programação 31
public class Floor {
private LinkedList<Room> rooms =
new LinkedList<Room>();
public Floor(final int numberOfRooms) {
for (int roomNumber = 1;
roomNumber != numberOfRooms + 1;
roomNumber++)
rooms.add(new Room(roomNumber));
}
public void show() {
for (Room room : rooms)
out.println(room);
}
}
2013/2014 Fundamentos de Programação 32
Mais tarde voltaremos a este assunto.
 Interfaces
 Definem comportamentos (adjectivam)
 Classes implementam-nas
 Listas
 Listas ligadas
 Operações sobre listas ligadas
 Introdução aos iteradores
2013/2014 Fundamentos de Programação
Página
33
 Interfaces
 Listas e listas ligadas
 Iteradores
2013/2014 Fundamentos de Programação
Página
34

14. Interfaces; Listas e cadeias ligadas; Iteradores – Fundamentos de Programação

  • 1.
    Interfaces Listas e listasligadas Iteradores
  • 2.
     Polimorfismo desubtipos  Classes e operações polimórficas  Herança  Ligação estática e ligação dinâmica  Classes abstractas e classes concretas  Operações abstractas  Análise, desenho e implementação  Dicionário do domínio  Conceitos  Conceitos concretos e conceitos abstractos 2013/2014 Fundamentos de Programação 2
  • 3.
     Definem umcomportamento que as classes podem implementar  Contêm apenas constantes e declarações de operações (e tipos embutidos)  Classes podem implementar interfaces  Uma classe pode implementar várias interfaces, embora possa derivar apenas de uma outra classe  Uma interface pode estender (derivar de) outra 2013/2014 Fundamentos de Programação 3
  • 4.
    public interface Comparable<Type>{ int compareTo(Type object); } public interface Queue<Item> { Item element(); void add(Item item); void remove(); } 2013/2014 Fundamentos de Programação 4 Operações apenas declaradas. Não se define qualquer método. Não é necessário usar o qualificador abstract. Operações públicas por omissão. Nota: A interface Queue é um pouco diferente na biblioteca do Java! Interface genérica. Type é um parâmetro. O correspondente argumento tem de ser um tipo.
  • 5.
    public final classRational implements Comparable<Rational> { private final int numerator; private final int denominator; … @Override public int compareTo(final Rational another) { final int leftNumerator = getNumerator() * another.getDenominator(); final int rightNumerator = another.getNumerator() * getDenominator(); if (leftNumerator > rightNumerator) return 1; if (leftNumerator < rightNumerator) return -1; return 0; } … } 2013/2014 Fundamentos de Programação 5
  • 6.
    public final classRational implements Comparable<Rational> { private final int numerator; private final int denominator; … public int compareTo(final Rational another){ … } … } Implementação 2013/2014 Fundamentos de Programação 6 «interface» Comparable<Type → Rational> Rational Relação de realização Comparable<Type → Rational> Rational
  • 7.
    public class CustomerQueueimplements Queue<Customer> { … } public class MyQueueTester { … public static void main(final String[] arguments) { Queue<Customer> customerQueue = new CustomerQueue(); … } … } 2013/2014 Fundamentos de Programação 7 Queue<Item → Customer> CustomerQueue
  • 8.
     Adjectivo denotandopossibilidade de realizar determinadas operações (e.g., Comparable)  Nome denotando conceito cujo comportamento será implementado (e.g., Queue) 2013/2014 Fundamentos de Programação 8 Caso semelhante ao das classes abstractas, mas 1. não há qualquer herança de implementação (i.e., de atributos não constantes e métodos) e 2. uma classe que implemente a interface pode simultaneamente implementar outras interfaces.
  • 9.
     Precisa-se declasses semelhantes  Com operações semelhantes  Com atributos semelhantes  Variando apenas em alguns tipos (e.g., o tipo dos elementos a guardar em diferentes listas)  É necessário definir essas classes separadamente? 2013/2014 Fundamentos de Programação 9
  • 10.
    public class ArrayList{ private Object[] items; … } 2013/2014 Fundamentos de Programação 10 - items * ObjectArrayList Room
  • 11.
    public class ArrayList<Item>{ private Item[] items; … } 2013/2014 Fundamentos de Programação 11 ArrayList<Item → Room> Room * - items ArrayList Item «bind» <Item → Room> - items : Item [*] Notação UML para classes genéricas (também conhecidas por modelos ou templates). Classe genérica. Item é um parâmetro. O correspondente argumento tem de ser um tipo.
  • 12.
    public class Floor{ private ArrayList<Room> rooms = new ArrayList<Room>(); public Floor(final int numberOfRooms) { for (int roomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++) rooms.addFirst(new Room(roomNumber)); } public void show() { while (rooms.hasNext()) out.println(rooms.next()); } } 2013/2014 Fundamentos de Programação 12 Inserir novo elemento no início ou a meio da lista implica «empurrar» elementos existentes para «fazer espaço». Para fazer isto o que é preciso?
  • 13.
    public class LinkedList<Item>{ private Node<Item> firstNode = null; private Node<Item> currentNode = null; … private static class Node<Item> { private Node<Item> nextNode; private Item item; private Node(final Node<Item> nextNode, final Item item) { this.nextNode = nextNode; this.item = item; } } … } 2013/2014 Fundamentos de Programação 13 Classe embutida (nested) privada. A classe LinkedList<Item> tem acesso aos membros privados de Node<Item>.
  • 14.
    2013/2014 Fundamentos deProgramação 14 LinkedList Item Node Item - nextNode: Node - item: Item LinkedList Item - firstNode: Node<Item> - currentNode: Node<Item> Node Item - nextNode: Node - item: Item Notações para o embutimento. LinkedList::Node Item - nextNode: Node - item: Item LinkedList Item - firstNode: Node<Item> - currentNode: Node<Item>
  • 15.
    public class Floor{ private LinkedList<Room> rooms = new LinkedList<Room>(); public Floor(final int numberOfRooms) { for (int roomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++) rooms.addFirst(new Room(roomNumber)); } public void show() { while (rooms.hasNext()) out.println(rooms.next()); } } 2013/2014 Fundamentos de Programação 15 Inserir novo elemento no início ou no meio da lista não implica «empurrar» elementos existentes!
  • 16.
    2013/2014 Fundamentos deProgramação 16 rooms : LinkedList<Item → Room> : Node<Item → Room> firstNode currentNode nextNode item item nextNode = null : Room : Node<Item → Room> : Room
  • 17.
    public class LinkedList<Item>{ private Node<Item> firstNode = null; … private static class Node<Item> { … private Node(final Node<Item> nextNode, final Item item) { this.nextNode = nextNode; this.item = item; } } public void addFirst(final Item newItem) { firstNode = new Node<Item>(firstNode, newItem); } … } 2013/2014 Fundamentos de Programação 17
  • 18.
    2013/2014 Fundamentos deProgramação 18 rooms : LinkedList<Item → Room> : Node<Item → Room> firstNode currentNode nextNode item item nextNode = null : Room : Node<Item → Room> : RoomnewItem : Room : Node<Item → Room> nextNode item firstNode
  • 19.
    public class LinkedList<Item>{ … public void removeFirst() { if (isEmpty()) throw new NoSuchElementException(…); if (currentNode == firstNode) currentNode = currentNode.nextNode; Node<Item> nextFirstNode = firstNode.nextNode; firstNode.item = null; firstNode.nextNode = null; firstNode = nextFirstNode; } … } 2013/2014 Fundamentos de Programação 19
  • 20.
    2013/2014 Fundamentos deProgramação 20 rooms : LinkedList<Item → Room> : Node<Item → Room> firstNode currentNode nextNode item item nextNode = null : Room : Node<Item → Room> : Room item = null nextFirstNode : «ref» Node<Item → Room> firstNode
  • 21.
    public class LinkedList<Item>{ … public void addLast(final Item newItem) { if (firstNode == null) firstNode = new Node<Item>(null, newItem); else lastNode().nextNode = new Node<Item>(null, newItem); } private Node<Item> lastNode() { Node<Item> node = firstNode; while (node.nextNode != null) node = node.nextNode; return node; } … } 2013/2014 Fundamentos de Programação 21
  • 22.
    public class LinkedList<Item>{ … public void addLast(final Item newItem) { if (firstNode == null) firstNode = new Node<Item>(null, newItem); else { Node<Item> lastNode = firstNode; while (lastNode.nextNode != null) lastNode = lastNode.nextNode; lastNode.nextNode = new Node<Item>(null, newItem); } } … } 2013/2014 Fundamentos de Programação 22
  • 23.
    2013/2014 Fundamentos deProgramação 23 rooms : LinkedList<Item → Room> : Node<Item → Room> firstNode currentNode nextNode item item nextNode = null : Room : Node<Item → Room> : Room lastNode : «ref» Node<Item → Room> nextNode = null : Node<Item → Room> nextNode newItem : Room item
  • 24.
    public class LinkedList<Item>{ … public Item next() { if (!hasNext()) throw new NoSuchElementException("…"); if (currentNode == null) currentNode = firstNode; else currentNode = currentNode.nextNode; return currentNode.item; } … } 2013/2014 Fundamentos de Programação 24
  • 25.
    2013/2014 Fundamentos deProgramação 25 rooms : LinkedList<Item → Room> : Node<Item → Room> firstNode currentNode nextNode item item : Room : Node<Item → Room> : Room nextNode = null : Node<Item → Room> nextNode item currentNode : Room
  • 26.
    2013/2014 Fundamentos deProgramação 26 LinkedList Item Node Ite m - item: Item nextNode firstNode currentNode 0..1 0..1 0..1 0..1 Esta solução não permite percorrer a lista mais do que uma vez em paralelo! 0..1 0..1 1 *
  • 27.
    public class Floor{ private LinkedList<Room> rooms = new LinkedList<Room>(); public Floor(final int numberOfRooms) { for (int roomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++) rooms.add(new Room(roomNumber)); } public void show() { while (rooms.hasNext()) out.println(rooms.next()); } } 2013/2014 Fundamentos de Programação 27
  • 28.
    public class Floor{ private LinkedList<Room> rooms = new LinkedList<Room>(); public Floor(final int numberOfRooms) { for (int roomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++) rooms.add(new Room(roomNumber)); } public void show() { LinkedList<Room>.Iterator i = rooms.iterator(); while(i.hasNext()) out.println(i.next()); } } 2013/2014 Fundamentos de Programação 28
  • 29.
    public class Floor{ private LinkedList<Room> rooms = new LinkedList<Room>(); public Floor(final int numberOfRooms) { for (int roomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++) rooms.add(new Room(roomNumber)); } public void show() { Iterator<Room> i = rooms.iterator(); while(i.hasNext()) out.println(i.next()); } } 2013/2014 Fundamentos de Programação 29
  • 30.
    Iterator é uma classeinterna (inner). As suas instâncias têm uma ligação implícita à instância da classe envolvente que as criou. A ver com pormenor mais tarde. 2013/2014 Fundamentos de Programação 30 LinkedList Item Node Item - item: Item nextNode firstNode currentNode 0..10..1 0..1 Esta solução permite percorrer a lista mais do que uma vez em paralelo! Iterator LinkedList.this * 0..1 0..1 * * 1
  • 31.
     Permitem iterarao longo de uma sequência de elementos, actuando sobre essa sequência  A uma sequência podem associar-se vários iteradores  Classes que forneçam iteradores podem ser usadas em ciclos for-each…  … mas têm de implementar a interface Iterable 2013/2014 Fundamentos de Programação 31
  • 32.
    public class Floor{ private LinkedList<Room> rooms = new LinkedList<Room>(); public Floor(final int numberOfRooms) { for (int roomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++) rooms.add(new Room(roomNumber)); } public void show() { for (Room room : rooms) out.println(room); } } 2013/2014 Fundamentos de Programação 32 Mais tarde voltaremos a este assunto.
  • 33.
     Interfaces  Definemcomportamentos (adjectivam)  Classes implementam-nas  Listas  Listas ligadas  Operações sobre listas ligadas  Introdução aos iteradores 2013/2014 Fundamentos de Programação Página 33
  • 34.
     Interfaces  Listase listas ligadas  Iteradores 2013/2014 Fundamentos de Programação Página 34

Notas do Editor

  • #4 Apesar de terem pontos em comum, as interfaces diferem conceptualmente e na prática das classes abstractas.
  • #5 Note-se que aqui introduzimos dois conceitos em simultâneo: o de interface e o de definição de um tipo genérico. No entanto, as interfaces podem não ser genéricas! Note-se que quando nos limitamos a declarar uma operação (e.g., uma operação numa interface ou uma operação abstracta numa classe), não há qualquer utilidade em qualificar os seus parâmetros como final. De facto, nos parâmetros, o qualificador final é uma protecção adicional para o programador enquanto implementador da operação! Comparable é semelhante a java.lang.Comparable. Queue é semelhante a java.util.Queue.
  • #6 Note-se que a classe Rational declara implementar a interface Comparable parametrizada consigo mesma! No final podia usar-se simplesmente return leftNumerator - rightNumerator. Esta implementação não tenta evitar a ultrapassagem dos limites dos int!
  • #7 A relação entre uma interface e uma sua implementação é de realização. Uma implementação realiza uma interface.
  • #8 As interfaces, tal como as classes, são tipos. O polimorfismo não se aplica apenas entre classes, mas entre tipos em geral. Uma instância de um subtipo pode (deve poder!) ser tratada como se fosse do respectivo tipo.
  • #9 A segunda possibilidade não é isenta de problemas. Temos os patos e temos também aquilo que “walks like a duck and swims like a duck and quacks like a duck” mas não é um pato. Limita-se a comportar-se como tal. Damos o nome Duck à classe ou à interface e isso gera confusão ou mesmo conflito. Talvez a segunda devesse ser Duckish ou DuckLike…
  • #10 O que é constante e o que varia? Esta é a base da identificação de unidades de modularização parametrizáveis. A genericidade em Java é uma forma de polimorfismo paramétrico!
  • #11 Solução péssima do Java original. Os elementos tinham de ser tratados como objectos (que têm disponível um comportamento limitado). Alternativamente, podia usar-se coerções de tipo, mas que tinham a particularidade infeliz de poder falhar em tempo de execução!
  • #12 Agora sim!
  • #13 A implementação (e discussão!) dos médodos add, hasNext e next fica como exercício para o leitor.
  • #14 A ideia é que os itens são guardados em nós possuídos pela lista e que se encadeiam uns nos outros, ficando a lista com uma ligação para o primeiro.
  • #15 Em rigor, apenas a notação inferior esquerda existe no UML. As restantes notações existem no UML mas apenas no que diz respeito a pacotes. Abusa-se aqui um pouco, por isso, da notação oficial.
  • #16 A implementação (e discussão!) do médodo hasNext fica como exercício para o leitor. Os restantes são desenvolvidos mais à frente. Na realidade faz mais sentido inserir os novos quartos no final da lista. 
  • #17 Na realidade deveria escrever-se LinkedList<E → Room>::Node<E → Room>, mas é muito longo para um diapositivo!
  • #28 Código já visto. Ver em sequência com o próximo diapositivo.
  • #29 Note-se que a classe Iterator está definida dentro da classe LinkedList<Room>. É necessário um método adicional na lista: iterator().
  • #30 A classe LinkedList<Room>.Iterator implementará a interface java.util.Iterator<Room>.
  • #31 Este diapositivo é animado. Conceptualmente os nós são parte da lista. Mas a navegação faz-se usando uma ligação para o primeiro nó e de cada nó para o seguinte.
  • #33 A classe LinkedList<Room>.Iterator implementará a interface java.util.Iterator<Room>.