Upload
vuongxuyen
View
217
Download
0
Embed Size (px)
Citation preview
LEEC@IST Java – 1/31
Programação por Objectos
Java
Parte 7: Interfaces
LEEC@IST Java – 2/31
Interfaces – revisão (1)
• Uma interface é um conjunto de protótipos de métodos (sem implementações) que especifica um serviço bem definido:– As interfaces não podem conter atributos, mas podem
conter constantes.
– A implementação duma interface é realizada pela classe
concreta. Na implementação ou concretização:• Determina-se os atributos necessários à correcta
implementação da interface.
• Descreve-se o código dos métodos das interface.
LEEC@IST Java – 3/31
Interfaces – revisão (2)
– Uma interface pode herdar as definições de outra interface.• Interfaces podem usar polimorfismo.
• Se uma classe concretizar mais de uma interface, e váriasinterfaces contiverem métodos com a mesma assinatura, bastadefinir uma única implementação.
– Uma interface não pode ser instanciada.
LEEC@IST Java – 4/31
Interfaces (1)
• Tanto as classes como as interfaces definem tipos (a unidade fundamental da programação OO).
• Em Java, uma classe só pode estender uma outra classe, mas pode implementar uma ou mais interfaces.
• Para uma dada classe, as classes estendidas e as interfaces implementadas são denominadas supertipos. A classe em si édenominada o subtipo.
• Uma referência para um objecto do subtipo pode ser usada sempre que uma referência para um objecto dos seus supertipos (classes ou interfaces) é necessária.
LEEC@IST Java – 5/31
Interfaces (2)
• O Java disponibiliza um conjunto de interfaces, de onde se destaca:– Comparable: objectos deste tipo têm uma ordem associada
que os permite comparar.– Iterable: objectos deste tipo disponibilizam um iterador, e
portanto podem ser usadas no ciclo for-each.• Collection: objectos deste tipo conseguem guardar
outros objectos.– Set, List, Queue, …
LEEC@IST Java – 6/31
Interfaces (3)
SintaxeQualif* interface Ident [ extends IdentI [, IdentI ]*] {
[ QualifC* Tipo IdentC = expressão; ] *
[ QualifM* Tipo IdentM ( [TipoP IdentP [, TipoP IdentP ]*); ]*
}
• Qualif: qualificador (visibilidade, entre outros)
• Ident: identificador da interface
• extends IdentI: especialização de interface
LEEC@IST Java – 7/31
Interfaces (4)
• Qualificadores de interface:– public: interface publicamente acessível.
– abstract: a interface não pode ser instanciada.
• Por omissão do qualificador public, uma interface éapenas acessível no pacote onde está definida.
LEEC@IST Java – 8/31
Interfaces (5)
• Todas as interfaces são implicitamente abstract. Porconvenção, o qualificador abstract é omitido.
• Todos os membros são implicitamente public. Por convenção, o qualificador public é omitido.
• Todas as constantes são implicitamente public static final. Porconvenção, os qualificadores são omitidos.
• Todos os métodos são implicitamente public abstract. Porconvenção, os qualificadores são omitidos.
• Nenhum outro qualificador é permitido às contantes e métodosduma interface.
LEEC@IST Java – 9/31
Interfaces (6)
public interface Pilha {//métodosboolean vazia();Object topo();boolean adicionar(Object o);void remover();
}
LEEC@IST Java – 10/31
Herança de interfaces (1)
• Uma interface pode estender mais que uma interface.
• As interfaces que são estendidas são denominadas superinterfaces, enquanto que a nova interface é denominada subinterface.
• Uma subinterface herda todas as constantes declaradas nas suas superinterfaces.
• Se uma subinterface declara uma constante com o mesmo nome que uma constante herdada (independentemente do tipo), a constante da subinterface esconde a constante herdada.
• Na subinterface a constante herdada é acedida apenas pelo seu nome qualificado (superinterface.constante).
LEEC@IST Java – 11/31
Herança de interfaces (2)
interface X {int val = 1;
String strx = “X”;}
interface Y extends X {int val = 2;
int sum = val + X.val;String stry = “Y extends” + strx;
}
LEEC@IST Java – 12/31
Herança de interfaces (3)• Se uma interface herda duas ou mais constantes com o mesmo
nome, qualquer referência simples a essa constante é ambígua e resulta num erro de compilação.
interface A {String str = “A”;
}
interface B extends A {String str = “B”;
}
interface C extends A {String str = “C”;
}
interface D extends B, C {String d = A.str+B.str+C.str;
}
interface D extends B, C {String d = str;
}
Erro de compilação: qual str?
LEEC@IST Java – 13/31
Herança de interfaces (4)
• Uma subinterface herda todos os métodos declarados nas suas superinterfaces.
• Se uma subinterface declara um método com a mesma assinatura, a menos de um retorno covariante, que um ou mais métodos herdados, o método da subinterface é uma redefinição dos métodos herdados.
• Se uma subinterface herda mais do que um método com a mesma assinatura, a menos de um retorno covariante, a subinterface contém apenas um método – o método que retorna o subtipo comum.
LEEC@IST Java – 14/31
Herança de interfaces (5)
• Se um método da subinterface difere apenas no tipo de retorno de um método herdado, ou se dois métodos herdados diferem apenas no tipo de retorno, e estes retornos não são covariantes, há um erro de compilação.
• Se um método tem o mesmo nome, mas diferentes parâmetros que um método herdado, o método é uma sobreposição do método herdado.
LEEC@IST Java – 15/31
Herança de interfaces (6)interface X {
void xpto();
Number foo1();
Number foo2();
}
interface Z extends X, Y {void xpto(String s);
Integer foo1();
}
interface Y {Object foo1();
Object foo2();
}
• Métodos da interface Z:– public void xpto()
– public void xpto(String)
– public Integer foo1()
– public Number foo2()
LEEC@IST Java – 16/31
Implementação de interfaces (1)
• Uma classe identifica as interfaces que implementa, listando-as a seguir à palavra chave implements.
Sintaxe (revisão)
Qualif* class Ident
[ extends IdentC] [ implements IdentI [,IdentI]* ] {
[ Decl_atributos | Métodos ]*
}
LEEC@IST Java – 17/31
Implementação de interfaces (2)
• As interfaces que uma classe implementa são denominadas as superinterfaces da classe.
• A classe deve disponibilizar uma implementação para todos os métodos definidos nas suas superinterfaces, senão a classe tem de ser declarada abstract.
LEEC@IST Java – 18/31
Implementação de interfaces (3)
• Quando um classe implementa uma interface, a classe pode aceder às constantes definidas na interface como se tivessem sido declaradas na classe.
• Uma classe que implementa mais do que uma interface, ou que estende uma classe e implementa uma ou mais interfaces, sofre dos mesmo problemas de constantes escondidas e ambiguidade que uma interface que estende mais de uma interface (ver slides 10, 11 e 12).
LEEC@IST Java – 19/31
Implementação de interfaces (4)
interface X {int val = 1;
String strx = “X”;}
interface Y extends X {int val = 2;
int sum = val + X.val;String stry = “Y extends ” + strx;
}
class Z implements Y {int val = 3;
}Z z = new Z();
System.out.println(“z.val=” + z.val +“ ((Y)z).val=” + ((Y)z).val + /* ou Y.val */“ ((X)z).val=” + ((X)z).val) /* ou X.val */;
System.out.println(“z.strx=” + z.strx + “ z.stry=” + z.stry;
No terminal é impresso z.val=3 ((Y)z).val=2 ((X)z).val=1
strx=X stry=Y extends X
LEEC@IST Java – 20/31
Implementação de interfaces (5)
interface A {String str = “A”;
}
interface B extends A {String str = “B”;
}
interface C extends A {String str = “C”;
}
class D implements B, C {String d = A.str+B.str+C.str;
}
class D implements B, C {String d = str;
}
Erro de compilação: qual str?
LEEC@IST Java – 21/31
Implementação de interfaces (6)
• Se uma classe implementa várias interfaces com mais do que um método com a mesma assinatura a classe contém apenas um tal método.
• Se uma classe implementa várias interfaces com mais do que um método com a mesma assinatura, a menos de um retorno covariante, a implementação deve definir o método que retorna o subtipo comum (caso contrário resulta num erro de compilação).
• Se uma classe implementa várias interfaces com mais do que um método que difere apenas no tipo de retorno, e estes retornos não são covariantes, há um erro de compilação.
LEEC@IST Java – 22/31
Implementação de interfaces (7)
interface X {void xpto();
Number foo1();
Number foo2();
}
interface Z extends X, Y {void xpto(String s);
Integer foo1();
}
interface Y {Object foo1();
Object foo2();
}
class ClasseZ implements Z {public void xpto() {...}
public void xpto(String s) {...}
public Integer foo1() {...}
public Number foo2() {...}
}
É importante identificar os métodos a implementar de uma interface: se a ClasseZ não disponibilizar a implementação para todos os métodos definidos nas suas superinterfaces tem de ser declarada abstract (ver slide 17).
LEEC@IST Java – 23/31
Implementação de interfaces (8)
• A implementação da interface Pilha pode ser feita de diferentes maneiras:– Baseada numa tabela: PilhaComTabela
– Baseada numa lista ligada: PilhaComLista
• A interface Pilha corresponde ao tipo de dados abstracto, enquanto que ambas as classes PilhaComTabela e PilhaComLista correspondem ao tipo de dados
implementado de duas formas diferentes.
public interface Pilha {//métodosboolean vazia();Object topo();boolean adicionar(Object obj);void remover();
}
LEEC@IST Java – 24/31
Implementação de interfaces (9)
public class PilhaComTabela implements Pilha {
private final int MAX;private Object pilha[];private int posLivre; // primeira posição livre
public PilhaComTabela(int max) {MAX = max;pilha = new Object[MAX]; posLivre = 0;
}public boolean vazia() {
return posLivre==0; }public Object topo() {
return pilha[posLivre]; }
LEEC@IST Java – 25/31
Implementação de interfaces (10)
//continuação do slide anterior...
public boolean adicionar(Object obj){if (posLivre<MAX-1){
pilha[posLivre++] = obj;return true;
}else return false;
}public void remover() {
pilha[posLivre--] = null;}public int numMaxElementos() {
return MAX;}
}
LEEC@IST Java – 26/31
Implementação de interfaces (11)
public class PilhaComLista implements Pilha {
private ElementoPilha topo;private int numElementos;
public PilhaComLista(){topo = null;numElementos = 0;
}public boolean vazia() {
return numElementos==0; }public Object topo() {
return topo!=null?topo.elemento:null;}
LEEC@IST Java – 27/31
Implementação de interfaces (12)
//continuação do slide anterior...
public boolean adicionar(Object obj){topo = new ElementoPilha(obj,topo);numElementos++;return true;
}public void remover() {
if (topo!=null) {topo = topo.próximo;numElementos--;
}}public int numElementos() {
return numElementos;}
}
LEEC@IST Java – 28/31
Implementação de interfaces (13)
public class ElementoPilha {
Object elemento;ElementoPilha próximo;
public ElementoPilha(Object elem, ElementoPilha prox){elemento = elem;próximo = prox;
}}
LEEC@IST Java – 29/31
Implementação de interfaces (14)
• Definindo as interfaces um tipo, é possível declarar variáveis com o seu tipo:
• Contudo, referências para um tipo de interface, só podem ser usadas para aceder a membros da própria interface:
• Para contornar este problema pode usar-se um cast:
Pilha p = new PilhaComTabela(100);
p.adicionar(new Integer(100));p.adicionar(new Character(‘a’));p.remover();
int max = ((PilhaComTabela)p).numMaxElementos();
int max = p.numMaxElementos(); //INVÁLIDO!!!
LEEC@IST Java – 30/31
Implementação de interfaces (15)
• É possível chamar qualquer método de Object com uma referência para um tipo de interface:
String s = p.toString();
LEEC@IST Java – 31/31
Implementação de interfaces (16)
• O programador pode instanciar a pilha que mais lhe interessa:
• Se houver interesse em usar PilhaComTabela, em vez de PilhaComLista, a única alteração reside na instanciação dos objectos, e não na declaração das referências para o tipoPilha:
Pilha p1 = new PilhaComLista();Pilha p2 = new PilhaComLista();
p1.adicionar(new Integer(5));p2.adicionar(new Character(‘a’));
Pilha p1 = new PilhaComTabela(20);Pilha p2 = new PilhaComTabela(100);
p1.adicionar(new Integer(5));p2.adicionar(new Character(‘a’));