Buscar

POO 19 interfaces

Prévia do material em texto

INTERFACES
Thaís Alves Burity Rocha
Agenda
 Introdução
 Interface
 Exemplo da API de Java: Classe Arrays, Classe
Collections e Interface Comparable
 Implementação de múltiplas interfaces
 Utilidade
Relembrando…
 Polimorfismo significa que uma chamada de método 
pode ser executada de várias formas
 Um contrato ou interface de acesso, várias implementações
 Onde ContaAbstrata é aceita, Conta, Poupanca, 
ContaBonificada e ContaImposto também é
ContaAbstrata
creditar()
debitar()
transferir()
Conta
Poupanca
ContaBonificada
ContaImposto
Usuário do objeto
enxerga apenas
esse “contrato”
Polimorfismo
 Achar o método certo a ser chamado para um 
objeto em particular chama-se dynamic binding
(ligação dinâmica) 
 O tipo real do objeto é identificado em tempo de 
execução 
 Portanto, a versão do método a ser executada também 
é definida em tempo de execução
 Já sabemos disso!
Interface x Implementação
 O contrato separa a interface de acesso da 
implementação
 A classe base define uma interface comum
 Não precisa dizer como vai ser feito
 Diz apenas as operação suportadas, especificando
suas entradas e saídas
 É possível debitar, creditar e transferir de uma conta
ContaAbstrata
creditar()
debitar()
transferir()
Usando Herança na Definição de 
Contratos
 Subclasses de ContaAbstrata herdam todos os seus 
métodos (não-private)
 Significa que é herdado o tipo da superclasse e 
também sua implementação
 Ao herdar, a subclasse pode substituir alguns 
métodos
 ContaBonificada sobrescreveu creditar
 Usando classes/métodos abstratos é possível exigir 
a sobrescrita de métodos
 É o caso do método debitar
Usando Herança na Definição de 
Contratos
 Em se tratando de conta bancária, faz sentido
haver herança
 Comportamentos comuns podem ser reusados
 Comportamentos distintos podem ser ajustados
 Sobrescrita de métodos (abstratos e não-abstratos)
 Há polimorfismo
Definição de Contrato Sem Herança
 Em outros casos, é desejável haver um contrato, mas 
não faz sentido reusar comportamento
 Contrato polimorfismo
 Exemplo: Repositório de dados
 Contrato: Operações de CRUD
 Diferentes formas de armazenamento
 Memória (volátil): Vetor, ArrayList…
 Disco (permanente): Arquivos
 Banco de Dados (permanente, facilita a consulta dos dados)
Definição de Contrato Sem Herança: 
Uma Possível Solução
public abstract class RepositorioContas {
public abstract void adicionar(ContaAbstrata conta);
public abstract void remover(ContaAbstrata conta);
public abstract void atualizar(ContaAbstrata conta);
public abstract ContaAbstrata consultar(ContaAbstrata conta);
public abstract ContaAbstrata consultar(String numero); 
}
 Subclasses: RepositorioContasVetor, 
RepositorioContasArrayList, 
RepositorioContasArquivo, RepositorioContasBD
 Na prática, só está havendo herança de tipo
Interface
 Semelhante à uma classe
 Serve para definir contratos “sem haver herança”
 Polimorfismo
 Todos os métodos são implicitamente abstract e public
 É declarada com a palavra-chave interface
 Não pode ser instanciada
 Não possui construtor
 Foi feita para ser implementada: Palavra-chave
implements
Interface: Exemplo de Declaração
 É redundante declarar métodos como public e abstract
public interface IRepositorioContas {
public abstract void adicionar(ContaAbstrata conta);
void remover(ContaAbstrata conta);
void atualizar(ContaAbstrata conta);
ContaAbstrata consultar(ContaAbstrata conta);
ContaAbstrata consultar(String numero);
}
Convenção: Começar
nome de interface com I 
Interface
 Introduz os conceitos de:
 Supertipo: Definido pela interface
 Subtipo: Definido pela classe que implementa a 
interface
 Subtipos devem implementar todos os métodos
definidos na interface
 Caso contrário, devem ser declarados como classes 
abstratas
Interface: Exemplo de Implementação
public class RepositorioContasArrayList implements
IRepositorioContas {
private ArrayList<ContaAbstrata> array;
public RepositorioContasArrayList(){
array = new ArrayList<ContaAbstrata>();
}
public void adicionar(ContaAbstrata conta){
int indice = array.indexOf(conta);
if(indice == -1) array.add(conta);
else{
System.out.println("Não é possível adicionar 
uma conta igual a outra já existente!");
}
}
//demais métodos aqui
}
Sobrescrita
Interface: Exemplo de Implementação
public class RepositorioContasVetor implements IRepositorioContas{
private ContaAbstrata[] contas; private int indice;
public static final int TAMANHO = 5;
public RepositorioContasVetor(){
contas = new ContaAbstrata[TAMANHO];
}
public void adicionar(ContaAbstrata conta){
int i = this.procurarIndice(conta.getNumero());
if(i != -1){ System.out.println("A conta já existe.");
} else if(indice>=0 && indice<contas.length &&
contas[indice]==null){
contas[indice] = conta;
this.atualizarIndice();
}else{ System.out.println("O repositório está cheio.");
}
}
//demais métodos aqui
}
Sobrescrita
Interface
 Métodos não podem ser static
 Atributos são implicitamente constantes (static e 
final)
 Modificadores de acesso são os mesmos de classes
 default
 public
Interface e Constantes
 Classes que implementam uma interface herdam 
todas as constantes definidas na interface
 Podem usá-las como se fossem da própria classe
 Classes que não implementam uma dada interface 
podem usar suas constantes
 Como qualquer membro static:
 <nome da interface>.<nome da constante> 
Interface
 Não pode ser instanciada, mas pode ser
referenciada
IRepositorioContas rep = new RepositorioContasVetor();
ContaAbstrata conta = new Conta();
rep.adicionar(conta);
conta = new ContaBonificada();
rep.adicionar(conta);
E se a gente quiser usar outro repositório?
Classe java.util.Arrays
 Provê métodos estáticos para manipulação de vetores 
de qualquer tipo
 Ordenação de vetor: void Arrays.sort(vetor)
 Vetor de tipo primitivo: Ordenação natural
 Vetor de objetos: A classe do objeto deve implementar 
a interface Comparable (java.lang.Comparable)
 Método: public int compareTo(Object obj)
 Lógica: Dada a chamada a.compareTo(b)
 Retornar um inteiro <0, se a for “menor” que b
 Retornar um inteiro >0, se a for “maior” que b
 Retornar zero se a e b forem iguais
Classe java.util.Arrays: Exemplo
 Ordenar vetor de ContaAbstrata pelo saldo
public abstract class ContaAbstrata implements 
Comparable {
...
public int compareTo(Object obj){
ContaAbstrata conta = (ContaAbstrata) obj;
if(this.saldo>conta.getSaldo()) return 1;
else if(this.saldo<conta.getSaldo())return -1;
else return 0;
}
}
Classe java.util.Arrays: Exemplo
 Agora a chamada para o método de ordenação
 O ideal seria ter um método de ordenação no 
repositório de contas
ContaAbstrata[] vetor = repositorioConta.getContas();
Arrays.sort(vetor);
for(ContaAbstrata c: vetor){
System.out.println(c);
}
Classe java.util.Collections
 É possível ordenar um ArrayList usando o método
sort da classe java.util.Collections
 Também exige que a classe dos objetos no ArrayList
implemente a interface Comparable
//onde tinha ordenação de vetor
Arrays.sort(vetor);
//substituir por ordenação de ArrayList
Collections.sort(arrayList);
Implementação de Múltiplas Interfaces
 Uma classe pode implementar mais de uma 
interface
 Mecanismo simplificado de herança múltipla em Java
public class RadioRelogio implements Relogio, Radio {
public String getHoras(){ ...}
public void ligar(){ ... }
public void desligar(){ ... }
public void trocarEstacao(int frequencia){ ... }
}
public interface Relogio{
String getHoras();
}
public interface Radio{
void ligar();
void desligar();
void trocarEstacao(int frequencia);
}
Implementação de Múltiplas Interfaces
 Se as interfaces possuem uma constante com mesmo
nome, a classe não irá compilar
 O compilador não saberá qual o valor a ser utilizado
 Não há problema se as interfaces possuem métodos
com mesma assinatura
 A classe só precisará sobrescrever o método uma vez
Interfaces: Utilidade
 O principal benefício do uso de interface é o 
polimorfismo e, por consequência, flexibilidade
 Usar interface como argumento e tipo de retorno
garante que, na prática, poderá ser usado qualquer
tipo que implemente essa interface
 Interfaces definem funções/papéis que a classe
pode desempenhar
Interfaces: Utilidade
 Classes em diferentes hierarquias podem
implementar as mesmas interfaces
 Ocultação de informação (information hiding)
 Decompor o sistema em módulos
 Cada modulo contém uma parte interna e uma parte 
externa
 A parte interna é escondida de outros módulos
 A parte externa é o contrato, o que os outros módulos
enxergam
Quando criar uma classe, subclasse, 
classe abstrata ou interface?
 Não use herança quando a nova classe não passar
no teste É-UM com nenhuma outra
 Use herança quando tiver que criar uma versão
mais específica de uma classe e precisar sobrepor
ou adicionar novos comportamentos
Quando criar uma classe, subclasse, 
classe abstrata ou interface?
 Use uma classe abstrata quando quiser definir um 
contrato para um grupo de subclasses e tiver algum
código para ser reusado entre elas
 Use uma classe abstrata quando quiser garantir
que ninguém possa criar objetos da classe
Quando criar uma classe, subclasse, 
classe abstrata ou interface?
 Use uma interface quando quiser definir uma
função que outras classes possam desempenhar, 
independente de hierarquia de herança
 Lembre-se: Contratos estão menos vulneráveis à 
mudanças, pois não há implementação

Continue navegando