Baixe o app para aproveitar ainda mais
Prévia do material em texto
Herança Programação em Java Prof. Maurício Braga 2/32 Pilares da programação OO Encapsulamento Herança Polimorfismo 3/32 Herança É o mecanismo para definir uma nova classe em termos de uma já existente É o relacionamento entre classes de objetos que permite a uma classe possuir atributos e operações definidas por outra classe mais genérica. A classe mãe é chamada de superclasse e a classe filha de subclasse. 4/32 Exemplo Imagine um programa para gerenciar a folha de pagamento de uma empresa. Tal programa pode conter uma classe Empregado. A classe empregado é definida para o empregado comum, que possui um salário fixo. Entretanto, a empresa também possui empregados que possuem além do salário fixo, uma comissão sobre as vendas realizadas. Essa é a única diferença entre os dois tipos de funcionários. Como implementar no programa suporte a esse funcionário comissionado? 5/32 Exemplo class Empregado { private double salario; private String nome; public Empregado(String nome_emp, double val) { nome = nome_emp; if (val > 0) salario = val; } public double getSalario() { return salario; } // resto dos métodos omitidos para simplificar } 6/32 Solução utilizando encapsulamento Copiar todo o código da classe Empregado para uma nova classe EmpregadoComComissao, modificando a mesma para adicionar o suporte a comissões. Problemas desta solução: Necessidade de manter dois códigos: Sempre que for necessário adicionar/corrigir a classe Empregado, será necessário corrigir a classe EmpregadoComComissao também. A melhor solução é utilizar herança. 7/32 Exemplo class EmpregadoComComissao extends Empregado { private double comissao; private int numero_vendas; public EmpregadoComComissao(String n_emp, double val, double com) { super(n_emp, val); if (com > 0) comissao = com; } public void adicionarVendas(int vendas) { numero_vendas = numero_vendas + vendas; } public double calcularPagamento() { return getSalario() + comissao*numero_vendas; } } 8/32 Solução utilizando herança EmpregadoComComissão herda de Empregado, obtendo todos os métodos e atributos definidos nesta. Uma vez que um objeto do tipo EmpregadoComComissão é também um objeto do tipo Empregado, ele pode receber quaisquer mensagens que seriam enviadas a um objeto do tipo Empregado. 9/32 Exemplo public static void main(String[] args) { EmpregadoComComissao c = new EmpregadoComComissao(“Ricardo Silva”, 3500, 0.15); c.adicionarVendas(5); System.out.println(“Nome: ” + c.getNome()); System.out.println(“Salário Fixo: ” + c.getSalario()); System.out.println(“Salario total: ” + c.calcularPagamento()); } 10/32 Porque utilizar herança? Nem sempre encapsulamento é a melhor solução. Possibilidade de alterar o funcionamento herdado da classe mãe, criando uma classe mais adequada a um tipo de situação, sem precisar mexer na classe original. Possibilidade de criar classes mais específicas, reutilizando código de classes genéricas. 11/32 Hierarquia de classes Uma vez que subclasses podem ser superclasses de novas classes, podemos definir uma hierarquia de classes em nossos programas Podemos entender a hierarquia de classe como uma árvore que contém todas as classes que estão relacionadas através de herança. A hierarquia de classes em Java se inicia com a classe Object, definida em java.lang. Uma classe herda atributos e métodos de todos os seus ancestrais. Em Java, uma classe pode herdar diretamente de apenas uma classe (herança simples). E possível, entretanto, implementar várias interfaces. 12/32 Hierarquia de classes Conta ContaCorrente Poupança ContaEspecial Veículo Carro Moto CarroEsportivo 13/32 Validação da herança Como podemos saber quando devemos utilizar herança e não encapsulamento? A forma de validar herança é usar a frase “é um”. Exemplo: gato e animal mamífero. Todo gato é um animal mamífero. Todo mamífero é um gato (?) 14/32 Validação da herança Validar a herança implica em verificar se faz sentido tratar a classe filha da mesma forma que se trata a classe mãe Uma classe filha pode apenas adicionar funcionalidade em relação a classe mãe. Remover funcionalidade não é permitido. Caso haja necessidade de remover funcionalidade em relação a classe mãe, a hierarquia de classes deve ser revista. 15/32 Herança Mamífero Gato 16/32 Exercício Definir uma hierarquia envolvendo herança para as seguintes classes: Figura, polígono, triângulo,retângulo,quadrado,elipse e círculo 17/32 Solução Figura Retângulo ElipsePolígono Triângulo Quadrado Círculo 18/32 Herança Uma subclasse pode possuir os seguintes tipos de métodos: Herdados: Métodos que a subclasse adquiriu da superclasse. Sobreescritos: Métodos herdados que foram redefinidos na subclasse. Novos: Métodos adicionados na subclasse. 19/32 Sobreescrevendo métodos Uma subclasse pode modificar o funcionamento de métodos herdados sobreescrevendo os mesmos (overriding). O método novo (sobreescrito) substitui o código antigo presente na superclasse. Apenas métodos com acesso public e protected podem ser sobreescritos. 20/32 Sobreescrevendo métodos Se um método da subclasse sobrescrever um método da superclasse, a “visibilidade” do método não pode ser reduzida (um método não pode ser sobreescrito para se tornar menos acessível). Métodos protected podem ser declarados como protected ou public. Métodos public só podem ser declarados como public. 21/32 Herança Vantagem: reuso de código. Vantagem: poder utilizar um objeto descendente de uma classe X em um lugar onde é esperado um objeto da classe X. Extensibilidade: Poder criar novos subtipos de uma classe e utilizá-los aonde a superclasse é utilizada sem precisar recompilar o código. Possibilidade de escrever código genérico, sem precisar usar if/else e outros testes. Cuidado: O contrário não é possível (utilizar um ancestral em um lugar onde um descendente é utilizado). (possível) Desvantagem: A classe herda o tipo da classe mãe. Ex: Imagine que criássemos uma classe Cliente e fizéssemos ela herdar de Empregado, para poder reutilizar métodos e atributos desta classe como nome, endereço, CPF, etc. Nesse caso, Cliente se torna um Empregado também, podendo ser tratado como um (tendo atributos como salário, que não se aplica a um cliente). 22/32 Exemplo Considere um classe cujo objetivo é representar um ponto no espaço bidimensional (uma coordenada em um plano XY). Esta classe possui dois atributos, um para a coordenada X e outro para a coordenada Y, bem como métodos para acessar/modificar esses atributos. A classe dispõe ainda de um método que imprime os valores de seus atributos. 23/32 Exemplo class PontoBidimensional { private double x_coord; private double y_coord; public PontoBidimensional(double x, double y) { setCoordenadaX(x); setCoordenadaY(y); } public void setCoordenadaX(double x) { x_coord = x; } public void setCoordenadaY(double y) { y_coord = y; } 24/32 Exemplo public double getCoordenadaX() { return x_coord; } public double getCoordenadaY() { return y_coord; } public String toString() { return “Eu sou um ponto bidimensional.\n” + “Minha coordenada x: ” + getCoordenadaX() + “\n” + “Minha coordenada y: ” + getCoordenadaY() + “\n”; } } 25/32 Exemplo O métodotoString() é definido na classe Object (classe mãe de todos as classes em Java). Por se tratar de um método público, todas as classes em Java possuem este método. O método toString() na classe PontoBidimensional sobreescreve o método toString() da classe Object. E se quiséssemos representar um ponto no espaço tridimensional? 26/32 Exercício Escreva uma classe PontoTridimensional. Esta classe deve herdar de PontoBidimensional, adicionando um campo relativo a coordenada Z. Esta classe deve conter também o método toString(), sobreescrevendo o método da classe PontoBidimensional. 27/32 Solução class PontoTridimensional extends PontoBidimensional { private double z_coord; public PontoTridimensional(double x, double y, double z) { super(x,y); setCoordenadaZ(z); } public void setCoordenadaZ(double z) { z_coord = z; } 28/32 Solução public double getCoordenadaZ() { return z_coord; } public String toString() { return “Eu sou um ponto tridimensional.\n” + “Minha coordenada x: ” + getCoordenadaX() + “\n” + “Minha coordenada y: ” + getCoordenadaY() + “\n”; “Minha coordenada z: ” + getCoordenadaZ() + “\n”; } } 29/32 Solução public static void main(String[] args) { PontoBidimensional pb = new PontoBidimensional(3,4); PontoTridimensional pt = new PontoTridimensional(5,6,7); System.out.println(pb); System.out.println(pt); } 30/32 Solução O método toString() definido na classe PontoTridimensional sobreescreve o método toString() presente na classe PontoBidimensional, que por sua vez já sobreescrevia o toString() da classe Object. O método toString() da classe PontoBidimensional imprime as coordenadas X e Y presentes nessa classe. Já o método toString() da classe PontoTridimensional imprime as coordenadas X e Y que ela herdou de PontoBidimensional, bem como a coordenada Z definida nessa classe. O método toString() na classe PontoTridimensional não utilizou o código existente na classe PontoTridimensional, substituindo-o totalmente. 31/32 Exercício Escreva uma classe SegmentoReta. Esta classe deve conter dois pontos (PontoBidimensional) demarcando o ponto inicial e o ponto final do Segmento. A classe deve conter um construtor bem como métodos para calcular o comprimento do segmento bem como um método que retorna o ponto médio do segmento (PontoBidimensional). Herança Programação em Java Prof. Maurício Braga
Compartilhar