Baixe o app para aproveitar ainda mais
Prévia do material em texto
CLASSES ABSTRATAS Thaís Alves Burity Rocha Agenda Introdução Classe abstrata Método abstrato Redefinição do sistema bancário Boas práticas de programação OO Introdução: Sistema Bancário Até o momento… Conta define saldo e as operações básicas para manipular saldo (métodos creditar, debitar e transferir) Poupanca adiciona o atributo juros e um método para render juros ContaBonificada redefine o método de creditar Conta Poupanca ContaBonificada Introdução: Sistema Bancário Agora imagine que há um novo tipo de Conta public class ContaImposto extends Conta { private double taxaImposto; public ContaImposto(Cliente c, String n, double s) { super(c, n, s); taxaImposto = 0.02; } public void debitar(double valor) { double valorComImposto = valor + (valor*taxaImposto); saldo -= valorComImposto); } } Introdução: Sistema Bancário Adicionando ContaImposto na hierarquia… Conta Poupanca ContaBonificada ContaImposto Usa debitar() de Conta Usa debitar() de Conta Redefine debitar() Análise do Mecanismo de Herança Em uma hierarquia, existem características comuns entre as classes, mas também diferenças em relação à algumas funcionalidades Planejar o que deve ser comum e como tratar as diferenças nem sempre é trivial A complexidade tende a aumentar com o tamanho da hierarquia Análise do Mecanismo de Herança A sobrescrita de métodos permite personalizar comportamentos O que só é perceptível no código da subclasse ou na execução do programa Seria melhor se fosse possível identificar na superclasse os comportamento comuns e diferentes entre as classes Análise do Mecanismo de Herança Além disso, tanto a superclasse quanto as subclasses podem ser instanciadas para uso em outras classes Em alguns casos não faz sentido permitir que a superclasse seja instanciada Ainda assim, é interessante poder descrever os campos e métodos que as subclasses devem implementar Análise do Mecanismo de Herança No mundo real, faz sentido instanciar um objeto FormaBidimensional? No entanto, essa classe é importante porque define o comportamento esperado das subclasses FormaBidimensional Circulo Quadradro Triangulo Análise do Mecanismo de Herança Ou seja, em algumas situações queremos definir apenas um contrato O que deve ser feito e não como é feito Java oferece 2 recursos para a definição de contratos Classes abstratas Interfaces Classe Abstrata É declarada com abstract Pode conter métodos concretos e abstratos Métodos abstratos Não possuem corpo, só assinatura Também são declarados com abstract Não podem ser definidos em classes concretas A classe abstrata mais simples public abstract class ClasseAbstrata {} Classe Abstrata: Exemplos Classe abstrata com um método abstrato Classe abstrata com métodos abstrato e concreto public abstract class ClasseAbstrata { public abstract void metodoAbstrato(); } public abstract class ClasseAbstrata { public abstract void metodoAbstrato(); public void metodoConcreto(){} } Classe Abstrata Classe concreta com método abstrato Não pode ser instanciada, mas sim referenciada public class ClasseQualquer { public abstract void metodoAbstrato(); } public abstract class ClasseAbstrata {} public class ClasseConcreta extends ClasseAbstrata{} ClasseAbstrata ref1 = new ClasseConcreta(); ClasseAbstrata ref2 = new ClasseAbstrata(); Classe Abstrata No geral, foi feita para ser herdada Logo, não pode ser marcada como final A subclasse deve sobrescrever os métodos abstratos Cada subclasse define sua própria implementação A assinatura comum “garante” um comportamento Caso contrário, a subclasse também deverá ser abstrata Redefinição do Sistema Bancário Conta Poupanca ContaBonificada ContaImposto ContaAbstrata debitar() [abstrato] Adiciona renderJuros() Adiciona renderBonus() e redefine creditar() debitar() [concreto] debitar() [concreto] Classe ContaAbstrata public abstract class ContaAbstrata { protected Cliente cliente; protected String numero; protected double saldo; public ContaAbstrata(){} public ContaAbstrata(Cliente c, String n, double s){ this.cliente = c; this.numero = n; this.saldo = s; } //métodos public getters e setters para cada atributo public abstract void debitar(double valor); ... Classe ContaAbstrata public void creditar(double valor){ saldo += valor; } public void transferir(ContaAbstrata conta, double valor){ this.debitar(valor); conta.creditar(valor); } public boolean equals(Object obj){ if(obj instanceof ContaAbstrata){ ContaAbstrata conta2 = (ContaAbstrata)obj; if(this.numero.equals(conta2.getNumero()))return true; } return false; } public String toString(){ return "numero da conta: "+numero+"; titular: "+ cliente.getNome(); } } Classe Conta public class Conta extends ContaAbstrata { public Conta(){ super(); } public Conta(Cliente c, String n, double s){ super(c, n, s); } public void debitar(double valor) { saldo -= valor; } } Sem cobrança de juros Classe Poupança public class Poupanca extends Conta { private double juros = 0.2; public Poupanca(){ super(); } public Poupanca(Cliente c, String n, double s){ super(c,n,s); } public void renderJuros(){ this.creditar(saldo*juros); } } Classe ContaBonificada public class ContaBonificada extends Conta { private double bonus; private double taxaBonus = 0.1; public ContaBonificada(){ super();} public ContaBonificada(Cliente c, String n, double s){ super(c,n,s); } public void creditar(double valor){ bonus += (valor*taxaBonus); super.creditar(valor); } public void renderBonus(){ super.creditar(bonus); bonus = 0; } } Classe ContaImposto public class ContaImposto extends ContaAbstrata { private double taxaImposto = 0.02; public ContaImposto(){ super(); } public ContaImposto(Cliente c, String n, double s){ super(c,n,s); } public void debitar(double valor){ double valorFinal = valor + (valor*taxaImposto); saldo -= valorFinal; } } Com cobrança de juros E o Repositório de Contas? A classe deve ser modificada para suportar a classe mais geral (o tipo de conta mais genérico que existe) Comportamento polimórfico Ou seja, onde havia Conta, substituir por ContaAbstrata Classe RepositorioContas public class RepositorioContas { private ArrayList<ContaAbstrata> array; public RepositorioContas(){ 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 } Versão de RepositorioContas usando ArrayList Classes Abstratas e Membros static Uma classe abstrata pode conter métodos static Desde que tais métodos não sejam abstratos É o caso da classe java.util.Calendar da API de Java, para tratamento de datas Calendar calendar = Calendar.getInstance(); Se classes abstratas não podem ser instanciadas, o que esse método retorna? Classes Abstratas e Construtor Classes abstratas não podem ser instanciadas Mas podem ter construtor O construtor da classe abstrata só poderá ser chamado por construtores de suas subclasses Boas Práticas de Programação OO O uso de classes abstratas é adequadoquando não é possível generalizar comportamentos para toda uma hierarquia de classes Trata-se de uma forma de definir um contrato, mantendo-se a vantagem do reuso (herança) A existência de um contrato viabiliza o uso de polimorfismo
Compartilhar