interface

Propaganda
Programação por Objectos
Java
Parte 7: Interfaces
MEEC@IST
Java – 1/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.
MEEC@IST
Java – 2/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árias
interfaces contiverem métodos com a mesma assinatura, basta
definir uma única implementação.
– Uma interface não pode ser instanciada.
MEEC@IST
Java – 3/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.
MEEC@IST
Java – 4/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, …
MEEC@IST
Java – 5/31
Interfaces (3)
Sintaxe
Qualif* 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
MEEC@IST
Java – 6/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.
MEEC@IST
Java – 7/31
Interfaces (5)
• Todas as interfaces são implicitamente abstract. Por
convençã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. Por
convenção, os qualificadores são omitidos.
• Todos os métodos são implicitamente public abstract. Por
convenção, os qualificadores são omitidos.
• Nenhum outro qualificador é permitido às contantes e métodos
duma interface.
MEEC@IST
Java – 8/31
Interfaces (6)
public interface Pilha {
//métodos
boolean vazia();
Object topo();
boolean adicionar(Object o);
void remover();
}
MEEC@IST
Java – 9/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).
MEEC@IST
Java – 10/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;
}
MEEC@IST
Java – 11/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 D extends B, C {
String d = str;
}
interface C extends A {
String str = “C”;
}
interface D extends B, C {
String d = A.str+B.str+C.str;
}
Erro de compilação: qual str?
MEEC@IST
Java – 12/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.
MEEC@IST
Java – 13/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.
MEEC@IST
Java – 14/31
Herança de interfaces (6)
interface X {
void xpto();
Number foo1();
Number foo2();
}
interface Y {
Object foo1();
Object foo2();
}
interface Z extends X, Y {
void xpto(String s);
Integer foo1();
}
• Métodos da interface Z:
–
–
–
–
MEEC@IST
public
public
public
public
void xpto()
void xpto(String)
Integer foo1()
Number foo2()
Java – 15/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 ]*
}
MEEC@IST
Java – 16/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.
MEEC@IST
Java – 17/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).
MEEC@IST
Java – 18/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
MEEC@IST
z.val=3 ((Y)z).val=2 ((X)z).val=1
strx=X stry=Y extends X
Java – 19/31
Implementação de interfaces (5)
interface A {
String str = “A”;
}
interface B extends A {
String str = “B”;
}
class D implements B, C {
String d = str;
}
interface C extends A {
String str = “C”;
}
class D implements B, C {
String d = A.str+B.str+C.str;
}
Erro de compilação: qual str?
MEEC@IST
Java – 20/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.
MEEC@IST
Java – 21/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).
MEEC@IST
Java – 22/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.
MEEC@IST
public interface Pilha {
//métodos
boolean vazia();
Object topo();
boolean adicionar(Object obj);
void remover();
}
Java – 23/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 posLivre>0 ? pilha[posLivre-1] : null;
}
MEEC@IST
Java – 24/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;
}
return false;
}
public void remover() {
if (posLivre>0)
pilha[--posLivre] = null;
}
public int numMaxElementos() {
return MAX;
}
}
MEEC@IST
Java – 25/31
Implementação de interfaces (11)
public class PilhaComLista implements Pilha {
private ElementoPilha base;
private int numElementos;
public PilhaComLista(){
base = null;
numElementos = 0;
}
public boolean vazia() {
return numElementos==0;
}
public Object topo() {
return base!=null ? base.elemento : null;
}
MEEC@IST
Java – 26/31
Implementação de interfaces (12)
//continuação do slide anterior...
public boolean adicionar(Object obj){
base = new ElementoPilha(obj,base);
numElementos++;
return true;
}
public void remover() {
if (base!=null) {
base = base.proximo;
numElementos--;
}
}
public int numElementos() {
return numElementos;
}
}
MEEC@IST
Java – 27/31
Implementação de interfaces (13)
public class ElementoPilha {
Object elemento;
ElementoPilha proximo;
public ElementoPilha(Object elem, ElementoPilha prox){
elemento = elem;
proximo = prox;
}
}
MEEC@IST
Java – 28/31
Implementação de interfaces (14)
• Definindo as interfaces um tipo, é possível declarar variáveis
com o seu tipo:
Pilha p = new PilhaComTabela(100);
• Contudo, referências para um tipo de interface, só podem ser
usadas para aceder a membros da própria interface:
p.adicionar(new Integer(100));
p.adicionar(new Character(‘a’));
p.remover();
int max = p.numMaxElementos(); //INVÁLIDO!!!
• Para contornar este problema pode usar-se um cast:
int max = ((PilhaComTabela)p).numMaxElementos();
MEEC@IST
Java – 29/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();
MEEC@IST
Java – 30/31
Implementação de interfaces (16)
• O programador pode instanciar a pilha que mais lhe interessa:
Pilha p1 = new PilhaComLista();
Pilha p2 = new PilhaComLista();
p1.adicionar(new Integer(5));
p2.adicionar(new Character(‘a’));
• 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 tipo
Pilha:
Pilha p1 = new PilhaComTabela(20);
Pilha p2 = new PilhaComTabela(100);
p1.adicionar(new Integer(5));
p2.adicionar(new Character(‘a’));
MEEC@IST
Java – 31/31
Download