Aula 3InterfacesListas e listas ligadasIteradores
Na aula anteriorPolimorfismo de subtiposClasses e operações polimórficasHerançaLigação estática e ligação dinâmicaClasses abstractas e classes concretasOperações abstractasAnálise, desenho e implementaçãoDicionário do domínioConceitosConceitos concretos e conceitos abstractos2009/2010Programação Orientada por Objectos2
InterfacesDefinem um comportamento que as classes podem implementarContêm apenas constantes e declarações de operações (e tipos embutidos)Classes podem implementar interfacesUma classe pode implementar várias interfaces, embora possa derivar apenas de uma outra classeUma interface pode estender (derivar de) outra2009/2010Programação Orientada por Objectos3
Interfaces: definiçãopublic interface Comparable<T> {intcompareTo(T object);}public interface Queue<E> {    E element();voidadd(E e);void remove();}2009/2010Programação Orientada por Objectos4Interface genérica. T é um parâmetro. O correspondente argumento tem de ser um tipo.Nota: A interface Queue é um pouco diferente na biblioteca do Java!Operações públicas por omissão.Operações apenas declaradas. Não se define qualquer método. Não é necessário usar o qualificador abstract.
Interfaces: implementaçãopublic class Rational implements Comparable<Rational> {    private int numerator;    private int denominator;    …    public intcompareTo(final Rational another) {intleftNumerator = getNumerator() * another.getDenominator();intrightNumerator = another.getNumerator() * getDenominator();        if (leftNumerator > rightNumerator)            return 1;        if (leftNumerator < rightNumerator)            return -1;        return 0;    }    …}2009/2010Programação Orientada por Objectos5
public class Rational implements Comparable<Rational> {    private int numerator;    private int denominator;    …    public intcompareTo(final Rational another){        return getNumerator() * another.getDenominator()             - another.getNumerator() * getDenominator();    }    …}Interfaces: implementação2009/2010Programação OrientadaporObjectos6«interface»Comparable<T->Rational>ImplementaçãoRelação de realizaçãoComparable<T -> Rational>RationalRational
Interfaces: polimorfismopublicclassMyListimplementsQueue<Customer> {    …}publicclassMyListTester {    …publicstaticvoidmain(final String[] arguments) {Queue<Customer> customerQueue = newMyList();        …     }    … }2009/2010Programação Orientada por Objectos7Queue<E -> Customer>MyList
Interfaces: nomesAdjectivo denotando possibilidade de realizar determinadas operações (e.g., Comparable)Nome denotando conceito cujo comportamento será implementado (e.g., Queue)2009/2010Programação Orientada por Objectos8Caso semelhante ao das classes abstractas, masnão há qualquer herança de implementação (i.e., de atributos não constantes e métodos) euma classe que implemente a interface pode simultaneamente implementar outras interfaces.
GenericidadePrecisa-se de classes semelhantesCom operações semelhantesCom atributos semelhantesVariando apenas em alguns tipos (e.g., o tipo dos elementos a guardar em diferentes listas)É necessário definir essas classes separadamente?2009/2010Programação Orientada por Objectos9
Lista genérica?public class ArrayList {    private Object[] elements;    …}2009/2010Programação Orientada por Objectos10- elementsObjectArrayList*Room
Lista genérica: implementaçãopublic class ArrayList<E> {    private E[] elements;    …}2009/2010Programação Orientada por Objectos11Classe genérica. E é um parâmetro. O correspondente argumento tem de ser um tipo.ENotação UML para classes genéricas (também conhecidas por modelos ou templates).ArrayList- elements : E [*]«bind» <E -> Room>- elementsArrayList<E->Room>Room*
Lista genérica: utilizaçãopublicclassFloor {privateArrayList<Room> rooms =newArrayList<Room>();publicFloor(final intnumberOfRooms) {        for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.addFirst(newRoom(roomNumber));    }publicvoid show() {while (rooms.hasNext())            out.println(rooms.next());    }}2009/2010Programação OrientadaporObjectos12Inserir novo elemento no início ou a meio da lista implica “empurrar” elementos existentes para “fazer espaço”.Para fazer isto o que é preciso?
Lista ligada genérica: implementaçãopublic class LinkedList<E> {    Node<E> firstNode = null;    Node<E> currentNode = null;    …    private static class Node<E> {        private Node<E> nextNode;        private E element;        private Node(final Node<E> nextNode,                     final E element) {this.nextNode = nextNode;this.element = element;        }    }    …}2009/2010Programação Orientada por Objectos13Classe embutida (nested) privada. A classe LinkedList<E> tem acesso aos membros privados de Node<E>.
Lista ligada genérica: notação2009/2010Programação Orientada por Objectos14EELinkedListLinkedList- firstNode: Node<E>- currentNode: Node<E>ENode- nextNode: Node- element: EENotações para o embutimento.Node- nextNode: Node- element: EEELinkedListLinkedList::Node- firstNode: Node<E>- currentNode: Node<E>- nextNode: Node- element: E
Lista ligada genérica: utilizaçãopublicclassFloor {privateLinkedList<Room> rooms =newLinkedList<Room>();publicFloor(final intnumberOfRooms) {        for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.addFirst(newRoom(roomNumber));    }publicvoid show() {while (rooms.hasNext())            out.println(rooms.next());    }}2009/2010Programação OrientadaporObjectos15Inserir novo elemento no início ou no meio da lista não implica “empurrar” elementos existentes!
Lista ligada genérica: Exemplo2009/2010Programação Orientada por Objectos16rooms : LinkedList<E->Room>firstNodecurrentNodenextNode: Node<E -> Room>: Node<E -> Room>nextNode = nullelementelement: Room: Room
Lista ligada genérica: inserir no iníciopublic class LinkedList<E> {    Node<E> firstNode = null;    …    private static class Node<E> {        …        private Node(final Node<E> nextNode,                     final E element) {this.nextNode = nextNode;this.element = element;        }    }    public void addFirst(final E newElement) {firstNode = new Node<E>(firstNode, newElement);    }    …}2009/2010Programação Orientada por Objectos17
Lista ligada genérica: inserir no início2009/2010Programação Orientada por Objectos18rooms : LinkedList<E->Room>firstNodefirstNodecurrentNodenextNodenextNode: Node<E -> Room>: Node<E -> Room>: Node<E -> Room>nextNode = nullelementelementelement: Room: RoomnewElement : Room
Lista ligada genérica: remover do iníciopublic class LinkedList<E> {    …    public void removeFirst() {        if (isEmpty())            throw new NoSuchElementException(…);        if (currentNode == firstNode)currentNode = currentNode.nextNode;        Node<E> nextFirstNode = firstNode.nextNode;firstNode.element = null;firstNode.nextNode = null;firstNode = nextFirstNode;    }    …}2009/2010Programação Orientada por Objectos19
Lista ligada genérica: remover do início2009/2010Programação Orientada por Objectos20rooms : LinkedList<E->Room>firstNodecurrentNodefirstNodenextNode: Node<E -> Room>: Node<E -> Room>element = nullnextNode = nullelementelement: Room: RoomnextFirstNode : «ref» Node<E -> Room>
Lista ligada genérica: inserir no fimpublic class LinkedList<E> {    …    public void addLast(final E element) {        if (firstNode == null)firstNode = new Node<E>(null, element);        elselastNode().nextNode = new Node<E>(null, element);    }    private Node<E> lastNode() {        Node<E> node = firstNode;        while (node.nextNode != null)            node = node.nextNode;        return node;    }    …}2009/2010Programação Orientada por Objectos21
Lista ligada genérica: inserir no fimpublic class LinkedList<E> {    …    public void addLast(final E element) {        if (firstNode == null)firstNode = new Node<E>(null, element);        else {            Node<E> lastNode = firstNode;            while (lastNode.nextNode != null)lastNode = lastNode.nextNode;lastNode.nextNode = new Node<E>(null, element);        }    }    …}2009/2010Programação Orientada por Objectos22
Lista ligada genérica: inserir no fim2009/2010Programação Orientada por Objectos23rooms : LinkedList<E->Room>firstNodecurrentNodenextNodenextNode: Node<E -> Room>: Node<E -> Room>: Node<E -> Room>nextNode = nullnextNode = nullelementelementelement: Room: RoomnewElement : RoomlastNode : «ref» Node<E -> Room>
Lista ligada genérica: passar ao seguintepublic class LinkedList<E> {    …    public E next() {        if (!hasNext())            throw new NoSuchElementException(“…");        if (currentNode == null)currentNode = firstNode;        elsecurrentNode = currentNode.nextNode;        return currentNode.element;    }    …}2009/2010Programação Orientada por Objectos24
Lista ligada genérica: passar ao seguinte2009/2010Programação Orientada por Objectos25rooms : LinkedList<E->Room>firstNodecurrentNodecurrentNodenextNodenextNode: Node<E -> Room>: Node<E -> Room>: Node<E -> Room>nextNode = nullnextNode = nullelementelementelement: Room: RoomnewElement : Room
Lista ligada genérica: notação2009/2010Programação Orientada por Objectos261ELinkedListEsta solução não permite percorrer a lista mais do que uma vez em paralelo!0..10..10..1currentNodeENode0..1firstNode0..1- element: E*nextNode0..1
Lista ligada genérica: iteradorespublicclassFloor {privateLinkedList<Room> rooms =newLinkedList<Room>();publicFloor(final intnumberOfRooms) {        for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.add(newRoom(roomNumber));    }publicvoid show() {while (rooms.hasNext())            out.println(rooms.next());    }}2009/2010Programação OrientadaporObjectos27
Lista ligada genérica: iteradorespublicclassFloor {privateLinkedList<Room> rooms =newLinkedList<Room>();publicFloor(final intnumberOfRooms) {        for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.add(newRoom(roomNumber));    }publicvoid show() {LinkedList<Room>.Iterator i = rooms.iterator();while(i.hasNext())            out.println(i.next());    }}2009/2010Programação OrientadaporObjectos28
Lista ligada genérica: notação2009/2010Programação Orientada por Objectos29ELinkedList0..1LinkedList.this1E*NodeIterator é umaclasse 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. 0..10..1*IteratorcurrentNodefirstNode0..1Esta solução permite percorrer a lista mais do que uma vez em paralelo!- element: E*0..1nextNode
IteradoresPermitem iterar ao longo de uma sequência de elementos, actuando sobre essa sequênciaA uma sequência podem associar-se vários iteradoresClasses que forneçam iteradores podem ser usadas em ciclos for-each2009/2010Programação Orientada por Objectos30Mais tarde voltaremos a este assunto.
A reter…InterfacesDefinem comportamentos (adjectivam)Classes implementam-nasListasListas ligadasOperações sobre listas ligadasIntrodução aos iteradores2009/2010Programação Orientada por ObjectosPágina 31
A ler para a próxima aula…Classes relativas a colecções na API do JavaCapítulos 1 a 10 e 16 do livro:Y. Daniel Liang, Introduction to Java Programming, 7.ª edição, Prentice-Hall, 2008.ISBN: 978-0-13-605966-02009/2010Programação Orientada por ObjectosPágina 32
Aula 3: SumárioInterfacesListas e listas ligadasIteradores2009/2010Programação Orientada por ObjectosPágina 33

Programação Orientada por Objectos - Aula 3

  • 1.
    Aula 3InterfacesListas elistas ligadasIteradores
  • 2.
    Na aula anteriorPolimorfismode subtiposClasses e operações polimórficasHerançaLigação estática e ligação dinâmicaClasses abstractas e classes concretasOperações abstractasAnálise, desenho e implementaçãoDicionário do domínioConceitosConceitos concretos e conceitos abstractos2009/2010Programação Orientada por Objectos2
  • 3.
    InterfacesDefinem um comportamentoque as classes podem implementarContêm apenas constantes e declarações de operações (e tipos embutidos)Classes podem implementar interfacesUma classe pode implementar várias interfaces, embora possa derivar apenas de uma outra classeUma interface pode estender (derivar de) outra2009/2010Programação Orientada por Objectos3
  • 4.
    Interfaces: definiçãopublic interfaceComparable<T> {intcompareTo(T object);}public interface Queue<E> { E element();voidadd(E e);void remove();}2009/2010Programação Orientada por Objectos4Interface genérica. T é um parâmetro. O correspondente argumento tem de ser um tipo.Nota: A interface Queue é um pouco diferente na biblioteca do Java!Operações públicas por omissão.Operações apenas declaradas. Não se define qualquer método. Não é necessário usar o qualificador abstract.
  • 5.
    Interfaces: implementaçãopublic classRational implements Comparable<Rational> { private int numerator; private int denominator; … public intcompareTo(final Rational another) {intleftNumerator = getNumerator() * another.getDenominator();intrightNumerator = another.getNumerator() * getDenominator(); if (leftNumerator > rightNumerator) return 1; if (leftNumerator < rightNumerator) return -1; return 0; } …}2009/2010Programação Orientada por Objectos5
  • 6.
    public class Rationalimplements Comparable<Rational> { private int numerator; private int denominator; … public intcompareTo(final Rational another){ return getNumerator() * another.getDenominator() - another.getNumerator() * getDenominator(); } …}Interfaces: implementação2009/2010Programação OrientadaporObjectos6«interface»Comparable<T->Rational>ImplementaçãoRelação de realizaçãoComparable<T -> Rational>RationalRational
  • 7.
    Interfaces: polimorfismopublicclassMyListimplementsQueue<Customer> { …}publicclassMyListTester { …publicstaticvoidmain(final String[] arguments) {Queue<Customer> customerQueue = newMyList(); … } … }2009/2010Programação Orientada por Objectos7Queue<E -> Customer>MyList
  • 8.
    Interfaces: nomesAdjectivo denotandopossibilidade de realizar determinadas operações (e.g., Comparable)Nome denotando conceito cujo comportamento será implementado (e.g., Queue)2009/2010Programação Orientada por Objectos8Caso semelhante ao das classes abstractas, masnão há qualquer herança de implementação (i.e., de atributos não constantes e métodos) euma classe que implemente a interface pode simultaneamente implementar outras interfaces.
  • 9.
    GenericidadePrecisa-se de classessemelhantesCom operações semelhantesCom atributos semelhantesVariando apenas em alguns tipos (e.g., o tipo dos elementos a guardar em diferentes listas)É necessário definir essas classes separadamente?2009/2010Programação Orientada por Objectos9
  • 10.
    Lista genérica?public classArrayList { private Object[] elements; …}2009/2010Programação Orientada por Objectos10- elementsObjectArrayList*Room
  • 11.
    Lista genérica: implementaçãopublicclass ArrayList<E> { private E[] elements; …}2009/2010Programação Orientada por Objectos11Classe genérica. E é um parâmetro. O correspondente argumento tem de ser um tipo.ENotação UML para classes genéricas (também conhecidas por modelos ou templates).ArrayList- elements : E [*]«bind» <E -> Room>- elementsArrayList<E->Room>Room*
  • 12.
    Lista genérica: utilizaçãopublicclassFloor{privateArrayList<Room> rooms =newArrayList<Room>();publicFloor(final intnumberOfRooms) { for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.addFirst(newRoom(roomNumber)); }publicvoid show() {while (rooms.hasNext()) out.println(rooms.next()); }}2009/2010Programação OrientadaporObjectos12Inserir 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.
    Lista ligada genérica:implementaçãopublic class LinkedList<E> { Node<E> firstNode = null; Node<E> currentNode = null; … private static class Node<E> { private Node<E> nextNode; private E element; private Node(final Node<E> nextNode, final E element) {this.nextNode = nextNode;this.element = element; } } …}2009/2010Programação Orientada por Objectos13Classe embutida (nested) privada. A classe LinkedList<E> tem acesso aos membros privados de Node<E>.
  • 14.
    Lista ligada genérica:notação2009/2010Programação Orientada por Objectos14EELinkedListLinkedList- firstNode: Node<E>- currentNode: Node<E>ENode- nextNode: Node- element: EENotações para o embutimento.Node- nextNode: Node- element: EEELinkedListLinkedList::Node- firstNode: Node<E>- currentNode: Node<E>- nextNode: Node- element: E
  • 15.
    Lista ligada genérica:utilizaçãopublicclassFloor {privateLinkedList<Room> rooms =newLinkedList<Room>();publicFloor(final intnumberOfRooms) { for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.addFirst(newRoom(roomNumber)); }publicvoid show() {while (rooms.hasNext()) out.println(rooms.next()); }}2009/2010Programação OrientadaporObjectos15Inserir novo elemento no início ou no meio da lista não implica “empurrar” elementos existentes!
  • 16.
    Lista ligada genérica:Exemplo2009/2010Programação Orientada por Objectos16rooms : LinkedList<E->Room>firstNodecurrentNodenextNode: Node<E -> Room>: Node<E -> Room>nextNode = nullelementelement: Room: Room
  • 17.
    Lista ligada genérica:inserir no iníciopublic class LinkedList<E> { Node<E> firstNode = null; … private static class Node<E> { … private Node(final Node<E> nextNode, final E element) {this.nextNode = nextNode;this.element = element; } } public void addFirst(final E newElement) {firstNode = new Node<E>(firstNode, newElement); } …}2009/2010Programação Orientada por Objectos17
  • 18.
    Lista ligada genérica:inserir no início2009/2010Programação Orientada por Objectos18rooms : LinkedList<E->Room>firstNodefirstNodecurrentNodenextNodenextNode: Node<E -> Room>: Node<E -> Room>: Node<E -> Room>nextNode = nullelementelementelement: Room: RoomnewElement : Room
  • 19.
    Lista ligada genérica:remover do iníciopublic class LinkedList<E> { … public void removeFirst() { if (isEmpty()) throw new NoSuchElementException(…); if (currentNode == firstNode)currentNode = currentNode.nextNode; Node<E> nextFirstNode = firstNode.nextNode;firstNode.element = null;firstNode.nextNode = null;firstNode = nextFirstNode; } …}2009/2010Programação Orientada por Objectos19
  • 20.
    Lista ligada genérica:remover do início2009/2010Programação Orientada por Objectos20rooms : LinkedList<E->Room>firstNodecurrentNodefirstNodenextNode: Node<E -> Room>: Node<E -> Room>element = nullnextNode = nullelementelement: Room: RoomnextFirstNode : «ref» Node<E -> Room>
  • 21.
    Lista ligada genérica:inserir no fimpublic class LinkedList<E> { … public void addLast(final E element) { if (firstNode == null)firstNode = new Node<E>(null, element); elselastNode().nextNode = new Node<E>(null, element); } private Node<E> lastNode() { Node<E> node = firstNode; while (node.nextNode != null) node = node.nextNode; return node; } …}2009/2010Programação Orientada por Objectos21
  • 22.
    Lista ligada genérica:inserir no fimpublic class LinkedList<E> { … public void addLast(final E element) { if (firstNode == null)firstNode = new Node<E>(null, element); else { Node<E> lastNode = firstNode; while (lastNode.nextNode != null)lastNode = lastNode.nextNode;lastNode.nextNode = new Node<E>(null, element); } } …}2009/2010Programação Orientada por Objectos22
  • 23.
    Lista ligada genérica:inserir no fim2009/2010Programação Orientada por Objectos23rooms : LinkedList<E->Room>firstNodecurrentNodenextNodenextNode: Node<E -> Room>: Node<E -> Room>: Node<E -> Room>nextNode = nullnextNode = nullelementelementelement: Room: RoomnewElement : RoomlastNode : «ref» Node<E -> Room>
  • 24.
    Lista ligada genérica:passar ao seguintepublic class LinkedList<E> { … public E next() { if (!hasNext()) throw new NoSuchElementException(“…"); if (currentNode == null)currentNode = firstNode; elsecurrentNode = currentNode.nextNode; return currentNode.element; } …}2009/2010Programação Orientada por Objectos24
  • 25.
    Lista ligada genérica:passar ao seguinte2009/2010Programação Orientada por Objectos25rooms : LinkedList<E->Room>firstNodecurrentNodecurrentNodenextNodenextNode: Node<E -> Room>: Node<E -> Room>: Node<E -> Room>nextNode = nullnextNode = nullelementelementelement: Room: RoomnewElement : Room
  • 26.
    Lista ligada genérica:notação2009/2010Programação Orientada por Objectos261ELinkedListEsta solução não permite percorrer a lista mais do que uma vez em paralelo!0..10..10..1currentNodeENode0..1firstNode0..1- element: E*nextNode0..1
  • 27.
    Lista ligada genérica:iteradorespublicclassFloor {privateLinkedList<Room> rooms =newLinkedList<Room>();publicFloor(final intnumberOfRooms) { for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.add(newRoom(roomNumber)); }publicvoid show() {while (rooms.hasNext()) out.println(rooms.next()); }}2009/2010Programação OrientadaporObjectos27
  • 28.
    Lista ligada genérica:iteradorespublicclassFloor {privateLinkedList<Room> rooms =newLinkedList<Room>();publicFloor(final intnumberOfRooms) { for (introomNumber = 1; roomNumber != numberOfRooms + 1; roomNumber++)rooms.add(newRoom(roomNumber)); }publicvoid show() {LinkedList<Room>.Iterator i = rooms.iterator();while(i.hasNext()) out.println(i.next()); }}2009/2010Programação OrientadaporObjectos28
  • 29.
    Lista ligada genérica:notação2009/2010Programação Orientada por Objectos29ELinkedList0..1LinkedList.this1E*NodeIterator é umaclasse 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. 0..10..1*IteratorcurrentNodefirstNode0..1Esta solução permite percorrer a lista mais do que uma vez em paralelo!- element: E*0..1nextNode
  • 30.
    IteradoresPermitem iterar aolongo de uma sequência de elementos, actuando sobre essa sequênciaA uma sequência podem associar-se vários iteradoresClasses que forneçam iteradores podem ser usadas em ciclos for-each2009/2010Programação Orientada por Objectos30Mais tarde voltaremos a este assunto.
  • 31.
    A reter…InterfacesDefinem comportamentos(adjectivam)Classes implementam-nasListasListas ligadasOperações sobre listas ligadasIntrodução aos iteradores2009/2010Programação Orientada por ObjectosPágina 31
  • 32.
    A ler paraa próxima aula…Classes relativas a colecções na API do JavaCapítulos 1 a 10 e 16 do livro:Y. Daniel Liang, Introduction to Java Programming, 7.ª edição, Prentice-Hall, 2008.ISBN: 978-0-13-605966-02009/2010Programação Orientada por ObjectosPágina 32
  • 33.
    Aula 3: SumárioInterfacesListase listas ligadasIteradores2009/2010Programação Orientada por ObjectosPágina 33