• Nenhum resultado encontrado

Classes Abstratas e Interfaces AULA 12

N/A
N/A
Protected

Academic year: 2021

Share "Classes Abstratas e Interfaces AULA 12"

Copied!
57
0
0

Texto

(1)

Ricardo Massa F. Lima [email protected]

Sérgio C. B. Soares [email protected]

Classes Abstratas e Interfaces AULA 12

Introdução a Programação – IF669 http://www.cin.ufpe.br/~if669

(2)

Até aqui

n 

Quando usar herança?

n 

Ao redefinir um método manter o

(3)

Adivinhem...

n 

Surge um novo requisito na aplicação

bancária

n 

Temos de cobrar um imposto em

certos tipos de contas

(4)

numero saldo

21.342-7

875,32

Objeto Conta Imposto

creditar

(5)

Número getSaldo 21.342-7 875,32 Crédito Débito

Estados do Objeto Conta

Imposto

numero saldo 21.342-7 875,00 debitar(20) creditar debitar Número getSaldo 21.342-7 875,32 Crédito Débito numero saldo 21.342-7 854,98 creditar debitar

(6)

Conta Imposto: Assinatura

Sem herança

public class ContaImposto {

public ContaImposto (String numero) {} public void creditar(double valor) {} public void debitar(double valor) {} public String getNumero() {}

public double getSaldo() {} }

(7)

Conta Imposto: Assinatura

Com herança

public class ContaImpostoM extends Conta { public ContaImpostoM(String numero) {} public void debitar(double valor) {} }

(8)

Conta Imposto: Descrição

Com herança

public class ContaImpostoM extends Conta { private static final double CPMF = 0.001; public ContaImpostoM (String numero) {

super (numero); }

public void debitar(double valor) { double imposto = (valor * CPMF);

super.debitar(valor + imposto); }

(9)

Subtipos e Subclasses

ContaImposto

(10)

Subclasses e

Comportamento (1)

n 

Objetos da subclasse devem se comportar

como os objetos da superclasse

•  Afinal de contas queremos usar objetos da

subclasse onde os objetos da superclasse são utilizados

public class Banco {

private Conta[] contas; private int indice; // ...

(11)

n 

Redefinições de métodos devem

preservar o comportamento

(semântica) do método original

•  No que diz respeito ao comportamento (e

atributos) herdado

n 

Grande impacto sobre manutenção/

evolução de software...

Subclasses e

(12)

Revisão/Otimização de

Código

... double m(Conta c) { c.creditar(10); c.debitar(10); return c.getSaldo(); } ...

Considerando apenas o retorno do método m, as duas opcões são sempre equivalentes?

Em que contextos? ... double m(Conta c) { return c.getSaldo(); } ...

(13)

Subclasses e Evolução de

Software

n 

Deveria ser possível raciocinar sobre o

código usando-se apenas a definição dos

tipos das variáveis envolvidas (Conta)

n 

O comportamento do código deveria ser

independente do tipo do objeto (Conta,

ContaEspecial, ContaImposto)

associado a uma dada variável em tempo

de execução

(14)

Reuso sem Subtipos

Conta

Poupanca ContaImpostoM

ContaEspecial

ContaImpostoM muda a semântica do método debitar e, se herdar de Conta, quebra a noção de subtipos!!!

(15)

Qual a alternativa então?

n  O que existe de comum entre Conta e

ContaImposto?

•  Vamos criar uma nova classe que

contenha essa parte em comum

• Conta e ContaImposto devem herdar

dessa nova classe

n  Atenção: debitar é diferente nas duas

classes

•  Mas ambas as contas devem permitir

(16)

Reuso preservando

Subtipos

ContaAbstrata ContaImposto Conta Poupanca ContaEspecial

(17)

Definindo Classes Abstratas

public abstract class ContaAbstrata { private String numero;

private double saldo;

public ContaAbstrata (String numero) { this.numero = numero;

this.saldo = 0.0; }

public void creditar(double valor) { this.saldo = this.saldo + valor; }

public double getSaldo() { return this.saldo;

}

(18)

public String getNumero() { return this.numero;

}

protected void setSaldo(double saldo) {

this.saldo = saldo; }

public abstract void debitar(double valor);

}

O método abstrato não tem implementação, mas

1.  Permite programar (não executar), chamando o método da classe abstrata (na classe Banco, por exemplo)

2.  Obriga que as subclasses concretas implementem o método

(19)

Revisão/Otimização de

Código

E agora, a modificação é correta? Em que contextos? ... double m(ContaA c) { c.creditar(10); c.debitar(10); return c.getSaldo(); } ... ... double m(ContaA c) { return c.getSaldo(); } ...

(20)

Classes Abstratas

n  Possibilita herança de código preservando

comportamento (semântica)

•  Não do método debitar, que ainda não possui

comportamento

n  Métodos abstratos:

•  geralmente, existe pelo menos um

•  são implementados nas subclasses

n  Não se cria objetos:

•  mas devem ter construtores para reuso

•  se necessário, métodos protected para serem

(21)

Contas: Descrição

Modificada

public class Conta extends ContaAbstrata { public Conta(String numero) {

super (numero); }

public void debitar(double valor) {

this.setSaldo(this.getSaldo() - valor); }

}

Implementação do método abstrato observe o uso do método protected

(22)

Poupanças: Descrição

Original

public class Poupanca extends Conta { public Poupanca(String numero) { super (numero);

}

public void renderJuros(double taxa) { this.creditar(this.getSaldo() * taxa); }

}

(23)

Conta Especial: Descrição

Original

public class ContaEspecial extends Conta { private static final double TAXA = 0.01; private double bonus;

public ContaEspecial (String numero) { super(numero);

this.bonus = 0.0; }

public void creditar(double valor) {

this.bonus = this.bonus + (valor * TAXA); super.creditar(valor);

}

(24)

Conta Imposto: Descrição

public class ContaImposto extends ContaAbstrata { private static final double CPMF = 0.001;

public ContaImposto (String numero) { super(numero);

}

public void debitar(double valor) { double imposto = valor * CPMF;

double total = valor + imposto;

super.setSaldo(this.getSaldo() – total);

} }

Implementação do método abstrato observe o uso do método protected

(25)

Substituição e Ligações

Dinâmicas

ContaAbstrata ca1, ca2;

ca1 = new ContaEspecial(“21.342-7”); ca2 = new ContaImposto(“21.987-8”); ca1.debitar(500);

ca2.debitar(500);

System.out.println(ca1.getSaldo()); System.out.println(ca2.getSaldo());

(26)

Classes Abstratas:

Utilização

n 

Herdar código sem quebrar noção de

subtipos, preservando o comportamento

do supertipo

n 

Generalizar código, através da abstração

de detalhes não relevantes

n 

Projetar sistemas, definindo as suas

arquiteturas e servindo de base para a

implementação progressiva dos mesmos

(27)

Contas: Projeto OO

public abstract class ContaProjeto { private String numero;

private double saldo; //...

public abstract void creditar(double valor); public abstract void debitar(double valor);

public String getNumero() { return numero;

protected setSaldo(double saldo) { this.saldo = saldo;

}

//... }

(28)

Outro exemplo

Pessoa: Reuso e Subtipos

Pessoa

PessoaFisica PessoaJuridica

(29)

Pessoa: Projeto OO

public abstract class Pessoa { private String nome;

...

public abstract String getCodigo(); }

(30)

public class PessoaFisica

extends Pessoa { private String cpf;

...

public String getCodigo() { return cpf;

} }

(31)

public class PessoaJuridica

extends Pessoa { private String cnpj;

...

public String getCodigo() { return cnpj;

} }

(32)

public class RepositorioPessoasArray { private Pessoa[] pessoas;

...

public Pessoa procurar(String codigo) { Pessoa p = null;

boolean achou = false;

for (int i=0; i<indice && !achou; i++) { p = pessoas[i]; if (p.getCodigo().equals(codigo)) achou = true; else p = null; } return p; } }

(33)

Exercício

n  Utilize a solução do último exercício

http://www.cin.ufpe.br/~if669/material/solucoes/aula12.zip

n  Defina no pacote aula13.br.ufpe.cin.banco, a classe abstrata

ContaAbstrata que tem os mesmos atributos e métodos de

Conta, só que o método debitar é abstrato, como visto em sala

n  Altere a classe Conta para herdar da classe ContaAbstrata e

implementar o método debitar

n  Modifique a classe Banco para que seja possível trabalhar com

todos os tipos de conta da aplicação bancária. Execute a classe Programa e observe que o teste funciona como antes

n  Defina a classe aula13.br.ufpe.cin.banco.ContaImposto que

herda de ContaAbstrata e tem uma constante CPMF que armazena o imposto a ser cobrado quando um valor for debitado na

ContaImposto

n  É necessário alterar as classes Poupanca e ContaEspecial?

(34)
(35)

Encapsulamento e

Information Hiding

n 

A habilidade em “esconder” de forma

segura dados e métodos de uma classe

dentro da “cápsula”da classe,

impedindo acesso de usuários não

confiáveis é conhecida como

information hiding

mas...por que estamos

(36)

Por que ecapsulamento com

information hiding

é útil?

n  Esconder detalhes de implementação

•  evita que outros programadores façam

uso dessas informações com algum propósito

•  torna possível modificar a

implementação com a segurança de que não afetará o código que utiliza a classe

(37)

n  Protege a classe de interferências externas

indesejáveis (sejam elas acidentais ou propositais)

•  A classe contém conjunto de campos

interdependentes, que devem ser mantidos em um estado consistente

•  Se for permitido a algum usuário externo (ou você

mesmo) modificar um campo sem modificar campos relacionados a ele, a classe ficará em um estado inconsistente

•  Se, por outro lado, o acesso é feito via um método,

há mais chances de que o estado será mudado de maneira consistente

Por que ecapsulamento com

(38)

n  Se todos os dados da classe estão

escondidos e podem ser acessados apenas via métodos da classe e esses métodos

foram bem testados, haverá maior garantia de que os dados serão modificados

consistentemente

n  Se, por outro lado, for permitido acesso

externo, o número de possibilidades a

serem testadas torna-se não gerenciável.

Por que ecapsulamento com

(39)

n  Se atributos públicos que são acessados

diretamente por outras classes forem modificados, as classes que os acessam diretamente serão afetadas

•  Acessando os mesmos com métodos pode evitar

esse impacto

n  Se um determinado método for definido

apenas para uso interno da classe,

esconder esse método evita que usuários da classe tentem usá-lo

Por que ecapsulamento com

(40)

Menos nobre, mas... se um campo ou método de uma classe for visível, você terá que

documentá-lo

economize seu tempo e esforço!

esconda os campos e métodos ao máximo!

Por que ecapsulamento com

(41)

Interfaces

n  Através do encapsulamento, os atributos e a

implementação dos métodos de uma certa classe não são visíveis ao usuário da classe

n  Conhecendo-se apenas a interface de uma classe, podemos

utilizar seus objetos sem conhecer detalhes de implementação

n  Uma interface inclui os métodos disponíveis e suas

respectivas assinaturas

n  Além disto, existem casos onde existe a necessidade de se

ter uma classe mas não queremos implementá-la

•  pode-se terceirizar a implementação, fornecendo como

(42)

Interfaces - Exemplo

n  Implementar um zoológico virtual com vários tipos de animais

n  Você gostaria de enviar as seguintes mensagens a cada animal:

•  nasca()

•  passeie()

•  durma()

•  peso()

n  Vamos pedir ajuda a programadores especialistas em cada

(43)
(44)

Interfaces - Exemplo

n  O programador que for implementar o morcego terá que dizer

explicitamente que vai usar a interface Animal •  palavra chave implements

A palavra chave implements

obriga o programador a escrever o código de todos os métodos na assinatura

Todos os métodos da interface devem ser públicos

(45)
(46)
(47)

Interfaces - Observação

Em cada arquivo deve existir no máximo uma classe pública! Logo, as classes Ornitorrinco, Morcego e Zebra devem estar em arquivos separados, com os respectivos nomes

(48)

Interfaces

Cada um dos animais, além de ser um objeto da própria classe, também é um objeto do tipo Animal

z2.contaListras() - Inválido z1.contaListras() -

(49)

Implementando mais de uma

interface por vez

n  Considere as duas interface:

(50)

Implementando mais de uma

interface por vez

(51)

Implementando mais de uma

interface por vez

Finalmente, podemos ver o Aviao que

(52)

Mas e na aplicação bancária?

Onde usar interfaces?

n  Hoje a classe Banco tem um array de Conta

n  E se amanhã quisermos utilizar outra

estrutura de dados?

n  E se quisermos depois de amanhã utilizar

um banco de dados?

n  Vamos desacoplar as regras de negócio do

(53)

Criar uma interface de

armazenamento de dados

public interface RepositorioContas { void inserir(ContaAbstrata conta);

ContaAbstrata procurar(String numero); void remover(String numero);

void atualizar(ContaAbstrata conta); boolean existe(String numero);

}

Todos os métodos são public e abstract por

(54)

Repositório: Implementações

public class RepositorioContasArray

implements RepositorioContas {...} public class RepositorioContasLista

implements RepositorioContas {...} public class RepositorioContasVector

implements RepositorioContas {...} public class RepositorioContasBDR

(55)

Banco

: Parametrização

public class Banco {

private RepositorioContas contas;

public Banco(RepositorioContas rep){ this.contas = rep;

}

public void cadastrar(ContaAbstrata conta){ String numero = conta.getNumero();

if (!contas.existe(numero)) { contas.inserir(conta);

} else {

throw new RuntimeException(“Já cad...);

}

// ... }

A estrutura para armazenamento das contas é

(56)

O que usar? Quando?

Classes (abstratas)

n  Agrupa objetos com

implementações compartilhadas

n  Define novas classes

através de herança (simples) de código

n  Uma classe pode ter

apenas uma como superclasse

Interfaces

n  Agrupa objetos com

implementações diferentes

n  Define novas interfaces

através de herança

(múltipla) de assinaturas

n  Uma classe pode ter

(57)

n  Utilize a solução dos exercícios da última aula

http://www.cin.ufpe.br/~if669/material/solucoes/aula13.zip

n  Defina no pacote aula14.br.ufpe.cin.dados a interface

RepositorioContas com os métodos

•  inserir – recebe uma ContaAbstrata e insere no repositório

•  procurar – recebe um número e retorna a conta se estiver no repositório

•  remover – recebe um número para remover a conta do repositório

•  atualizar - recebe uma ContaAbstrata para atualizar no repositório

•  existe – recebe um número e informa se existe uma conta com este

número no repositório

n  Modifique a classe Banco para utilizar a interface definida

(receba a implementação da interface no construtor)

•  Perceba que a classe Banco compila apenas com a interface. Já a

classe Programa precisa de uma implementação para executar.

n  Defina no pacote aula14.br.ufpe.cin.dados classe

RepositorioContasArray que implementa a interface RepositorioContas

n  Altere a classe Programa para fazer os testes

Referências

Documentos relacionados

Na atividade de hoje você irá fazer um desenho bem bonito desejando Feliz Natal a todos seus amiguinhos, depois com a ajuda de um adulto fotografe esse momento e envie para sua

Este índice é composto de 11 questões sobre dor, desconforto e função, sendo seis questões sobre dor e desconforto (sendo uma destas distintas para joelho e

Embora esteja cada vez mais bem documentada a magnitude da dispersão no meio ambiente de poluentes tóxicos produzidos pelo homem, poucas pessoas sabem que esses mesmos compostos

Entendendo a centralidade das lutas em favor dos camponeses que se recriam nas contradições da lógica do capital, seja na luta para se reproduzirem enquanto classe

Por isso, o mesmo mostrou-se completamente disposto para realização das extrações dentárias superiores e instalação de implantes osseointegrados na maxila com prótese de arco

A pesquisa resultante da utilização da palavra rede poderá devolver referências para documentos contendo assuntos relacionados com rede de computadores ou rede de pesca. A

A PRESIDENTE da Assembleia da República, Verónica Macamo, defende que as mulheres devem ser solidárias umas com as outras e evitarem a tendência de se

Monitoria em disciplinas vinculadas ao Curso de Fisioterapia, exercida por um período de, no mínimo, 1 (um) semestre letivo, com dedicação mínima de 10 (dez) horas semanais.