Baixe o app para aproveitar ainda mais
Prévia do material em texto
* * - Herança e Polimorfismo - Flávio Ferro Técnicas de Programação 1 * * Tópicos Herança Ligação Dinâmica Polimorfismo * * Herança Como aproveitar o comportamento já definido antes? Herança! * * Herança Herança é um conceito que mapeia as classes relacionadas entre si de maneira hierárquica Os descendentes de uma classe herdam todas as variáveis e métodos de seus ancestrais bem como podem criar seus próprios * * Herança Os descendentes são subclasses e o seu ascendente imediato é chamado de superclasse * * Herança Especialização e Generalização Na Generalização, há classes mais genéricas e abstratas disponíveis, as quais podem ser usadas para outras descenderem delas. Já a Especialização, há classes que estão numa posição inferior na hierarquia possuem estado e comportamento mais especializados. * * Classes em posição inferior como Automóvel, representam especializações de classes em posição superior (Transporte, Terrestre). Classes em posição superior como Transporte, representam generalizações de classes em posições inferiores (Automóvel, Terrestre). Especialização e Generalização * * * * * * * * * * Herança – Atributos e Métodos No esquema a classe ContaPoupanca possui os atributos (numero e saldo) e os métodos sacar, depositar, gets e sets, devido ao mecanismo de herança * * Implementando a Herança Em java a palavra-chave extends é usada como mecanismo para definição de herança e subtipos Java oferece suporte somente a herança simples de classes Por exemplo: public class ContaPoupanca extends Conta { ...} * * Lab1 - Implementando Herança 1. Defina a Classe Conta com os atributos encapsulados número e saldo. 2. Implemente os métodos de depósito e saque, assim como os métodos de acesso e mutação. 3. Defina a classe ContaPoupanca como uma uma subclasse da classe Conta. 4. Na classe TestaConta crie um objeto do tipo ContaPoupanca, inicialize cada atributo usando o método "set" . 5. Exiba os dados da conta poupança criada. * * Lab1.1 - Implementando Herança 1. Defina a Classe Funcionário com os atributos encapsulados nome, cpf e salário. 2. Implemente os métodos de acesso (get) e mutação (set). 3. Defina a classe Gerente como uma subclasse da classe Funcionário. 4. Um gerente no nosso banco possui uma senha numérica que permite o acesso ao sistema interno do banco. Implemente o método autentica para verificar a validade da senha e permitir ou não o acesso. * * Lab1.1 - Implementando Herança 5. Na classe TestaGerente crie um objeto do tipo Gerente, inicialize cada atributo usando o método "set“ e chame o método autentica para verificar a senha. 6. Exiba os dados do gerente criado e a permissão ou não do acesso. * * Herança - Restrições Atributos e métodos privados são herdados, mas não podem ser acessados Construtores não são herdados, são algo único a cada classe. * * A Keyword super Quando um método da subclasse redefinir um método da superclasse, pode-se acessar o método da superclasse através da palavra-chave super seguida de um ponto(.) Somente a palavra super pode ser utilizada para ativar o construtor da superclasse * * super public class Conta { private String numero; private double saldo; public Conta(String pNum){ numero = pNumero; } } class ContaPoupanca extends Conta{ int variacao; public ContaPoupanca (String pNum, int pVar){ super(pNum); variacao = pVar; } ... } public class TestaConta { public static void main (String [ ] args ) { Conta cc = new Conta(“cc001” ); ContaPoupanca cp = new ContaPoupanca(“cp001”,1); exibir os atributos de cc e cp... } } * * Lab1.2 - Implementando Herança (Super) 1. Defina a Classe Transporte. Inclua o atributo capacidade do tipo inteiro e modificador de acesso protected. 2. Implemente o construtor dessa classe passando o argumento capacidade, do tipo inteiro. 3. Defina a Classe Terrestre como uma subclasse da classe Transporte. Inclua o atributo número de rodas do tipo inteiro e modificador de acesso protected. 4. Implemente o construtor dessa classe passando os argumentos capacidade e número de rodas, ambos do tipo inteiro . * * Lab1.2 - Implementando Herança (Super) 5. Utilize a palavra-chave super para referenciar o construtor da superclasse Transporte. 6. Defina a Classe Automóvel como uma subclasse da classe Terrestre. Inclua os atributos número da placa (string), número de portas (inteiro) e modificador de acesso private. 7. Implemente o construtor dessa classe passando os argumentos capacidade e número de rodas (inteiros), número da placa (string), e número de portas (inteiro). Utilize a palavra-chave super para referenciar o construtor da superclasse Terrestre. 8. No programa principal crie um objeto do tipo automóvel utilizando o seu método construtor e exiba os valores. * * Herança – Adicionando Atributos e Métodos No esquema a classe ContaPoupanca além dos atributos (numero e saldo) e dos métodos sacar, depositar, gets e sets, agora possui membros próprios: O atributo anoBase Os métodos get e set do atributo ano base, e render * * Conta numero: String saldo: double boolean sacar(double v) ContaPoupanca boolean sacar(double v) Considerando data base Sobreposição/Redefinição/ Override Uma subclasse pode redefinir um método da superclasse utilizando a mesma assinatura, isto é chamado de sobreescrita/redefinição/ sobreposição ou override de método * * Quando a redefinição do método da superclasse não possuir a mesma assinatura na subclasse, isto não é anulação, mas sim sobrecarga de método Conta numero: String saldo: double boolean sacar(double v) ContaPoupanca boolean sacar(float v) Sobreposição/Redefinição/ Override * * Conta numero: String saldo: double boolean sacar(double v) ContaPoupanca String sacar(double v) ERRO !!! Dois métodos com o mesmo nome. Lembre-se que tipo de retorno não são considerados para overload. Se um método na subclasse possuir apenas o tipo de retorno diferente de um método da sua superclasse será gerado um erro (pois existirão dois métodos com o mesmo nome) Sobreposição/Redefinição/ Override * * A Keyword “final” Todos os métodos e variáveis de instância herdados podem ser sobrepostos Para não permitir que as subclasses sobreponham suas variáveis ou seus métodos, pode declará-las como final Por exemplo: final int ARQNOVO = 1; public final void imprime( ); * * Lab2 - Sobrepondo Métodos Implemente o método sacar na superclasse Conta. public void sacar(double pVal){ } Faça o override do método sacar na subclasse ContaPoupanca, que deve considerar uma data base (apenas imprima uma mensagem para considerar isso). Teste a implementação na classe TestaConta, chamando o método sacar da superclasse Conta e da subclasse ContaPoupanca. * * Lab2.1 - Sobrepondo Métodos Estenda o exercício Lab1.1 incluindo o método bonificação, no qual os funcionários comuns recebem 10% do valor do salário e os gerentes 15%. Crie o método bonificação para a superclasse Funcionário e para a subclasse Gerente. Teste a implementação na classe TestaGerente, de forma a aplicar o método bonificação para os Gerentes. Exibe o resultado. * * Lab2.2 - Sobrepondo Métodos Imagine que, para calcular a bonificação de um gerente, devemos fazer igual ao cálculo de um funcionário, porém adicionando R$ 1.000,00. Aqui teríamos um problema: o dia em que o getBonificação do funcionário mudar, precisaremos mudar o método do gerente, também para acompanhar a nova bonificação. Para evitar isso, o getBonificação do gerente pode chamar o do funcionário utilizando-se da palavra chave super. Implemente e exiba o resultado. * * Ligação Dinâmica e Polimorfismo* * Ligação Dinâmica A vinculação/ligação dinâmica permite determinar dinamicamente qual método será executado Para isso, deve-se declarar uma referência do tipo da superclasse e criado um objeto da subclasse A ligação dinâmica permite o polimorfismo A chamada do mesmo método pode assumir várias formas, dependendo do objeto criado em tempo de execução * * Polimorfismo Declarar uma referência da superclasse e instanciar objetos da subclasse Métodos com a mesma assinatura implementações diferentes Por exemplo: A classe conta e poupança possuem o método saque, o qual possui implementações diferentes devido à consideração de datas para o saque. OBS: A consideração importante é que todo objeto da subclasse (subtipo) é um objeto da superclasse (supertipo) * * public class TestaConta{ public static void main (String [ ] args ){ Conta c = new Conta (); c.setNumero("001"); c.setSaldo(100.0); System.out.println(c.sacar(100.0)); c = new ContaPoupanca(); c.setNumero("002"); c.setSaldo(200.0); System.out.println(c.sacar(100.0)); } } Polimorfismo * * public class TestaConta { public static void main (String [ ] args ){ Conta [ ] repContas = new Conta [3]; repContas [0] = new Conta (“cc1”,10.0); repContas [1] = new Conta (“cc2”,20.0); repContas [2] = new ContaPoupanca(“cp1”,10.0); repContas [3] = new ContaPoupanca(“cp2”,40.0 ); for (int i = 0; i <= 3; i++) System.out.println (repContas[i].sacar(10.0)); } } Polimorfismo * * Lab3 - Override de Métodos 1. Crie uma classe aplicativo (TestaConta) e defina uma referência do tipo Conta e crie um objeto desse tipo. 2. Chame o método sacar do objeto criado. 3. Faça a referência declarada na questão anterior apontar para um novo objeto do tipo ContaPoupanca. 4. Chame o método sacar do objeto conta poupança e observe o resultado. * * Verificação Dinâmica de Tipos - instanceof public class TestaConta { public static void main (String [ ] args ){ Conta [ ] repContas = new Conta [4]; repContas [0] = new Conta (“cc1”,10.0); repContas [1] = new Conta (“cc2”,20.0); repContas [2] = new ContaPoupanca(“cp1”,10.0); repContas [3] = new ContaPoupanca(“cp2”,40.0 ); for (int i = 0; i <= 3; i++) System.out.println (repContas[i].render()); } } Erro2: Execução. Solução: instanceof if (repContas[i] instanceof ContaPoupanca) System.out.println (((ContaPoupanca)repContas[i]).render()); Erro1: Compilação. O método render pertence somente ao subtipo(ContaPoupanca). Solução: Type Cast ((ContaPoupanca)repContas[i]).render() * * Verificação Dinâmica de Tipos - código corrigido public class TestaConta { public static void main (String [ ] args ){ Conta [ ] repContas = new Conta [4]; repContas [0] = new Conta (“cc1”,10.0); repContas [1] = new Conta (“cc2”,20.0); repContas [2] = new ContaPoupanca(“cp1”,10.0); repContas [3] = new ContaPoupanca(“cp2”,40.0 ); for (int i = 0; i <= 3; i++) if (repContas[i] instanceof ContaPoupanca) System.out.println (((ContaPoupanca)repContas[i]).render()); } } * * Lab 4 - Verificação Dinâmica de Tipos 1. Implemente, na classe conta poupança, um método render que deve acrescentar 1% sobre o saldo. 2. Na classe aplicativo, crie um array do tipo conta corrente com 3 posições. Armazene dois objetos do tipo conta corrente e um do tipo conta poupança. 3. Chame o método saldo dos objetos armazenados no array, execute e observe o resultado. * * Lab 4 - Verificação Dinâmica de Tipos 4. Ative o método render, compile e observe o resultado. 5. Corrija o erro de compilação verificando dinamicamente o tipo e execute o programa. 6. Corrija o erro usando cast e execute o programa. * * Pontos Principais - Herança Herança permite o reuso de dados (atributos) e operações (métodos) Para acessar membros da superclasse a partir da subclasse deve-se usar a palavra super Construtores não são herdados e a única forma de acesso a partir de uma subclasse é através da palavra super * * Pontos Principais - Herança A subclasse pode adicionar novos atributos e/ou métodos ou sobrepor (redefinir) métodos definidos em sua superclasse Na redefinição de métodos a subclasse deve preservar a assinatura: tipo de retorno, nome do método, quantidade e tipos dos argumentos * * Pontos Principais - Polimorfismo A ligação dinâmica permite o polimorfismo A chamada do mesmo método pode assumir várias formas, dependendo do objeto criado em tempo de execução Métodos com a mesma assinatura implementações diferentes Declarar uma referência da superclasse e instanciar objetos das subclasses Todo objeto da subclasse (subtipo) é um objeto da superclasse (supertipo) *
Compartilhar