Baixe o app para aproveitar ainda mais
Prévia do material em texto
Programação orientada a objetos: herança e polimorfismo APRESENTAÇÃO A reusabilidade de código é uma das grandes vantagens do desenvolvimento de softwares em linguagens de programação orientada a objetos. Pela estrutura de classes e construção de programas, pensando em abstrair entidades da realidade para o conceito de objetos, é possível que os códigos se tornem mais organizados e reutilizáveis. Quando se pensa em reusabilidade de código em orientação a objetos, é necessário conhecer como funciona o conceito de herança e polimorfismo. Nesta Unidade de Aprendizagem, você conhecerá o conceito e tipos de herança e polimorfismo na visão da orientação a objetos e também como são aplicados, utilizando exemplos em linguagem de programação orientada a objetos. Bons estudos. Ao final desta Unidade de Aprendizagem, você deve apresentar os seguintes aprendizados: Especificar a herança na orientação a objetos.• Discutir o polimorfismo na orientação a objetos.• Aplicar a herança e o polimorfismo.• DESAFIO A herança é um conceito da programação orientado a objetos que permitem o reuso de código. Por meio do conceito de herança, novas classes são criadas a partir de classes já existentes, absorvendo os seus atributos e métodos e adicionando os seus próprios. A partir disso, considere a seguinte situação: Conteúdo interativo disponível na plataforma de ensino! Com base em tais informações e utilizando o conceito de herança, apresente o modelo de classes e o modelo descritivo com os atributos e métodos das classes necessárias para atender a esse requisito. Utilize os métodos 'get' e 'set' para manipulação dos atributos de cada classe. INFOGRÁFICO O conceito de herança é um dos conceitos base da programação orientada a objetos. Qualquer linguagem de programação que implemente o paradigma de orientação a objetos deve permitir que a herança seja implementada. Neste Infográfico, você verá a sintetização de conceitos relacionados à herança entre classes, abordando a hierarquia de classes, herança simples e herança múltipla. CONTEÚDO DO LIVRO A programação orientada a objetos, sem dúvida, possibilitou que os programas de computadores ficassem mais próximos da realidade. Avanços relacionados à criação de programas em linguagens orientadas a objetos vão desde a facilidade de acoplação até mesmo a manutenção de sistemas. Outro benefício importante da programação orientada a objetos está ligado ao reuso de código. E, quando se fala em reuso de código em programação orientada a objetos, é necessário falar sobre herança e polimorfismo. No capítulo Programação orientada a objetos: herança e polimorfismo, da obra Paradigmas de programação, base teórica desta Unidade de Aprendizagem, você vai conhecer mais sobre esses conceitos da programação orientada a objetos, entender os tipos de herança e as formas de implementação de polimorfismo em linguagens orientadas a objetos. Boa leitura. PARADIGMAS DE PROGRAMAÇÃO Fabricio Machado da Silva Programação orientada a objetos: herança e polimorfismo Objetivos de aprendizagem Ao final deste texto, você deverá apresentar os seguintes aprendizados: � Especificar a herança na orientação a objetos. � Discutir o polimorfismo na orientação a objetos. � Aplicar a herança e o polimorfismo. Introdução O paradigma da programação orientada a objetos surgiu com o intuito de aplicar conceitos da realidade ao contexto da programação de com- putadores. O próprio nome, orientação a objetos, remete ao conceito de que o foco da construção dos programas está em orientar a estrutura para as entidades objetos, que emulam noções existentes no mundo real. Para que o paradigma de orientação a objetos tenha maior abrangên- cia, faz-se necessário que outros conceitos também sejam possíveis e, nesse escopo, ocorre a herança entre objetos. Assim como na realidade, no contexto da programação orientada a objetos, a herança está asso- ciada à característica de possuir comportamentos de outra entidade. Neste capítulo, iremos entender o funcionamento do conceito de herança na programação orientada a objetos. Além disso, abordaremos o conceito de polimorfismo, que permite que a herança entre objetos seja possível, mesmo com alterações no comportamento herdado, para atender a características específicas do objeto herdeiro. O conceito de herança na orientação a objetos O conceito de herança na programação orientada a objetos é utilizado para se permitir a reutilização de um código. A herança possibilita que classes compartilhem seus atributos e métodos entre si. Segundo Tucker e Noonan (2009, p. 335), [...] o paradigma orientado a objetos suporta reutilização de código por in- termédio da herança. As classes existem em uma linguagem orientada a objetos em uma hierarquia de classes. Uma classe pode ser declarada como uma subclasse de outra classe, que é chamada de classe mãe ou superclasse. Dentro dessa relação de hierarquia de classes é possível que a subclasse herde atributos e comportamentos da superclasse, simplesmente pelo fato de ser sua subordinada. Na programação orientada a objetos, a relação de herança entre classes é a relação em que uma classe é do tipo é uma, e não do tipo tem uma. Esta é uma das confusões recorrentes na construção de programas em orientação a objetos. Para ilustrar essa diferença, observe a Figura 1 e veja que, neste exemplo, temos um tipo de relação é uma, pois o objeto da classe Cachorro, assim como o objeto da classe Gato, é, por herança, um tipo de objeto da classe Animal. Figura 1. Representação de herança entre classes. Animal Cachorro Gato Programação orientada a objetos: herança e polimorfismo2 Compare, agora, a relação apresentada na Figura 2, que representa uma relação do tipo tem uma. Perceba que, neste caso, uma relação de herança entre as classes Estado e Cidade não faz sentido, visto que um estado possui cidades, mas uma cidade não é um estado. Figura 2. Representação da relação do tipo tem uma entre classes. Estado Cidade No conceito de herança, a superclasse geralmente é uma classe genérica, que engloba os atributos e métodos que podem ser utilizados por qualquer classe herdeira. Não faz sentido utilizar a superclasse para atribuir, por exem- plo, um atributo ou método que seja específico de uma subclasse, pois, neste caso, todas as demais subclasses estariam herdando este atributo ou método desnecessariamente. A herança pode apresentar duas formas diferentes. A mais comum e uti- lizada pelas linguagens de programação, em geral, é a herança simples. No entanto, algumas linguagens de programação orientada a objetos, como a linguagem C++ e Python, possibilitam a implementação da herança múltipla (TUCKER; NOONAN, 2009). Na herança simples, uma hierarquia de classe forma uma árvore, com sua raiz na classe genérica. Uma classe D é uma subclasse de outra classe C quando ela estende ou especializa o significado da classe C e acrescenta novas variáveis de instância ou métodos, ou quando modifica as definições dos métodos público e protegido de C. A herança múltipla, conforme já mencionado, é um recurso que também pode ser implementado por algumas linguagens de programação orientada a objetos. A linguagem Java, por exemplo, uma das linguagens orientada a objetos mais utilizadas não permite a implementação da herança múltipla. Em contraposição à herança simples, na herança múltipla uma classe pode herdar atributos e métodos de mais de uma superclasse, atribuindo a esta comportamentos de diferentes classes. 3Programação orientada a objetos: herança e polimorfismo Existem situações em que seu uso pode ser pertinente, mas a herança múl- tipla também possui desvantagens, especialmente em razão de sua semântica, que pode dificultar a manutenção do código. Conforme Lima (2014, p. 148) observa, [...] uma desvantagem da herança múltipla é que sua semântica se torna muito complicada em certas circunstâncias. Por exemplo, se uma classeE tem sub- classes B e C, e um método M é definido diferentemente em B e C, que imple- mentação de M deveria ser herdada por E: aquela em B, aquela em C ou ambas? Em alguns casos é necessário que a subclasse possua um comportamento diferenciado do que foi herdado da superclasse. Na orientação a objetos, cha- mamos esse conceito de polimorfismo. Na próxima seção, iremos abordá-lo no contexto da orientação a objetos. Polimorfismo O polimorfismo na programação orientada a objetos permite que uma ou mais classes derivadas de uma mesma superclasse possam invocar métodos que possuam uma mesma assinatura, mas com comportamentos diferenciados para cada classe derivada, utilizando, para isso, uma referência a um objeto da superclasse. A definição de polimorfismo é mais um dos recursos da orientação a objetos que possibilita que um comportamento encontrado na realidade seja aplicado à programação. Na natureza, existem animais que são capazes de modificar sua forma ou comportamento para atender a determinada situação, e é isto que o polimorfismo possibilita na programação orientada a objetos. Segundo Tucker e Noonan (2009, p. 323), “em linguagens orientadas a ob- jetos, polimorfismo refere-se à ligação tardia de uma chamada a uma ou várias diferentes implementações de um método em uma hierarquia de herança”. Para entendermos melhor este exemplo, suponhamos que uma aplicação implementa um programa de desenho. Em um programa desses, podemos ter diferentes formas geométricas: círculo, quadrado, retângulo etc. Programação orientada a objetos: herança e polimorfismo4 Cada uma das formas geométricas é representada, respectivamente, por uma das classes apontadas a seguir. � classe circulo; � classe quadrado; � classe retangulo. Todas essas classes são subclasses da classe FormaGeometrica. Temos, na superclasse FormaGeometrica, a definição do método desenhar, mas sabemos que desenhar um círculo é diferente de desenhar um retângulo. Neste caso, a forma de implementar o método desenhar na subclasse Circulo deve possuir um comportamento diferente da implementação na subclasse Retangulo, apesar de todas herdarem e necessitarem dessa implementação. Portanto, o conceito de polimorfismo serve justamente para resolver questões como esta. A Figura 3 ilustra um diagrama de classes com base nesta implementação. Figura 3. Representação de polimorfismo entre classes. FormaGeometrica Circulo desenhar() Quadrado Retangulo desenhar()desenhar() desenhar() 5Programação orientada a objetos: herança e polimorfismo Para Lima (2014), são dois os tipos mais recorrentes de polimorfismo na programação orientada a objetos: a) polimorfismo estático ou sobrecarga de método; b) polimorfismo dinâmico ou sobrescrita de método. O polimorfismo estático ou sobrecarga de método é a forma de implemen- tação em que são definidos vários métodos com o mesmo nome, mas com assinaturas diferentes. Ou seja, cada método pode receber diferentes parâmetros ou, então, os mesmos parâmetros de tipos diferentes. A sobrecarga consiste em permitir, dentro da mesma classe, mais de um método com o mesmo nome. Entretanto, eles devem necessariamente possuir argumentos diferentes para funcionar. Booch, Rumbaugh e Jacobson (2006) afirmam que a escolha de qual método irá ser chamado pelo programa principal dependerá do seu tipo de objeto, e esta decisão será tomada apenas no tempo de execução, por meio de ligação tardia. Veja o exemplo a seguir de um código em linguagem Java para uma classe Calculadora. Perceba que o método calcula aparece três vezes: o primeiro recebe como parâmetro dois valores int, o segundo recebe dois valores double e o terceiro recebe dois valores String. public class Calculadora { public int calcula(int a, int b) { return a+b; } public double calcula(double a, double b) { return a+b; } public String calcula(String a, String b) { return a+b; } } O polimorfismo dinâmico ou sobrescrita de método nos permite reescrever um método, ou seja, podemos reescrever nas subclasses os métodos criados inicialmente na superclasse. Os métodos que serão sobrepostos, diferentemente dos sobrecarregados, devem possuir o mesmo nome, tipo de retorno e quan- tidade de parâmetros do método inicial. No entanto, este será implementado Programação orientada a objetos: herança e polimorfismo6 com especificações da classe atual, podendo adicionar algo a mais ou não (LIMA, 2014). Para ilustrar este exemplo, vamos novamente utilizar um trecho de código de uma classe em linguagem Java. Primeiramente, observe a escrita do método setVelocidade na superclasse Veiculo: public abstract class Veiculo { public float velocidade; public void setVelocidade(float v) { velocidade = v; } } Veja, então, como ficaria a implementação na subclasse Carro. Observe que a assinatura do método é a mesma da superclasse, ou seja, recebe v como parâmetro do tipo float. Porém, na subclasse, além de atribuir o valor de v para velocidade, são feitos um tratamento e uma atribuição de valor ao atributo marcha, dependendo da velocidade do veículo. public abstract class Carro. { public float velocidade; public void setVelocidade(float v) { velocidade=v; if (velocidade < 20){ marcha = 1; } else if (velocidade >= 20 && velocidade < 40) { marcha = 2; } else if (velocidade >= 40 && velocidade < 60){ marcha = 3; } else if (velocidade >= 60 && velocidade < 70){ marcha = 4; } else if (velocidade >= 70){ marcha = 5; } } } 7Programação orientada a objetos: herança e polimorfismo Na próxima seção, iremos abordar um exemplo de aplicação de herança e polimorfismo em linguagens orientadas a objetos. Aplicação de herança e polimorfismo Nas seções anteriores, abordamos os conceitos de herança e polimorfismo em programação orientada a objetos, utilizando a linguagem de programação Java. Nesta seção, iremos apresentar a implementação destes conceitos na constru- ção de um programa para uma escola, no qual são utilizados os exemplos de herança entre as classes Professor e Aluno, que herdam de Pessoa, e o polimorfismo dinâmico, para o método obterDescontoMensalidade, que calcula o valor da mensalidade com desconto. A Figura 4 ilustra o modelo de classes para esta situação. Figura 4. Modelo de classes para situação proposta de um programa para uma escola. Pessoa nome: string cpf: string data_nascimento : Date newAttr : integer obterDescontoMensalidade(valor) Professor salario : double disciplina : String Aluno Matricula : String Programação orientada a objetos: herança e polimorfismo8 Primeiramente, vamos ver como ficaria a construção da superclasse Pessoa. public class Pessoa { public String nome; public String cpf; public Date data _ nascimento; public Pessoa (String _ nome, String _ cpf, Date _ data) { this.nome = _ nome; this.cpf = _ cpf; this.data _ nascimento = _ data; } } Após a criação da superclasse, vamos verificar os códigos utilizado para a criação das subclasses Aluno e Professor. Certifique-se de que sua declaração inclua as palavras extends Pessoa depois de Aluno. Essa sintaxe é da linguagem Java e significa que as subclasses devem herdar da superclasse Pessoa. public class Aluno extends Pessoa { public Aluno (String _ nome, String _ cpf, Date _ data) { super ( _ nome, _ cpf, _ data); } public String matricula; } public class Professor extends Pessoa { public Professor (String _ nome, String _ cpf, Date _ data) { super ( _ nome, _ cpf, _ data); } public double salario; public String disciplina; } 9Programação orientada a objetos: herança e polimorfismo Podemos verificar que, tanto na subclasse Aluno, quanto na subclasse Professor, o método construtor está utilizando os atributos que foram declarados na superclasse Pessoa: _ nome _ cpf _ data Além disso, observe que no caso da subclasseAluno é definido um atributo específico matricula, que só faz sentido para Aluno. No caso da subclasse Professor, os atributos salario e disciplina só fazem sentido no contexto de Professor. Estes exemplos ilustram o típico uso de herança, sem haver necessidade de reescrever nas subclasses o que é comum a elas, escrevendo somente o que lhes é específico. Agora, suponhamos que a escola resolveu criar um programa de oferta de descontos em mensalidades para Aluno e para Professor. Contudo, a diferença de percentual seria de 20% para os professores e apenas 10% para alunos. Vamos adotar o desconto de 10% como o desconto comum, logo, seria criado na superclasse Pessoa o método obterDescontoMensalidade para retornar o valor do desconto. Dessa forma, não é necessário fazer nenhuma alteração na subclasse Aluno, pois o comportamento será automaticamente herdado da superclasse Pessoa. public class Pessoa { public String nome; public String cpf; public Date data _ nascimento; public Pessoa (String _ nome, String _ cpf, Date _ data) { this.nome = _ nome; this.cpf = _ cpf; this.data _ nascimento = _ data; } public double obterDescontoMensalidade (double valor) { //Retorna o valor do desconto na mensalidade return 0.10 * valor; } } Programação orientada a objetos: herança e polimorfismo10 Como especificado na regra de negócio, os objetos da classe Professor devem receber um desconto diferenciado de 20%. Logo, utilizando o conceito de polimorfismo dinâmico, em que o método possui a mesma assinatura, apenas implementando um novo comportamento, vamos fazer um ajuste para atender a esta necessidade. Veja, então, como ficaria a subclasse Professor: public class Professor extends Pessoa { public Professor (String _ nome, String _ cpf, Date _ data) { super ( _ nome, _ cpf, _ data); } public double salario; public String disciplina; public double obterDescontoMensalidade (double valor) { //Retorna o valor do desconto na mensalidade return 0.20 * valor; } } Este foi um exemplo de aplicação simples da utilização em uma mesma estrutura de classes dos conceitos apresentados neste capítulo. Por fim, é possível verificar que herança e polimorfismo se relacionam no contexto das linguagens de programação orientada a objetos. Acesse o link a seguir para um exemplo de polimorfismo e herança em Python, uma importante linguagem de programação que permite a orientação a objetos. https://qrgo.page.link/6xYCs 11Programação orientada a objetos: herança e polimorfismo BOOCH, G.; RUMBAUGH, J.; JACOBSON, I. UML: guia do usuário. 2. ed. Rio de Janeiro: Elsevier; Campus, 2006. 474 p. LIMA, A. S. UML 2.5: do requisito à solução. São Paulo: Érica, 2014. 368 p. TUCKER, A. B.; NOONAN, R. E. Linguagens de programação: princípios e paradigmas. 2. ed. Porto Alegre: AMGH, 2009. 630 p. Leituras recomendadas EDELWEISS, N.; LIVI, M. A. C. Algoritmos e programação: com exemplos em Pascal e C. Porto Alegre: Bookman, 2014. 476 p. (Série Livros Didáticos Informática UFRGS). LEDUR, C. L. Desenvolvimento de sistemas com C#. Porto Alegre: SAGAH, 2018. 268 p. MACHADO, R. P.; FRANCO, M. H. I.; BERTAGNOLLI, S. C. Desenvolvimento de software III: programação de sistemas web orientada a objetos em Java. Porto Alegre: Bookman, 2016. 220 p. (Série Tekne; Eixo Informação e Comunicação). OKUYAMA, F. Y.; MILETTO, E. M.; NICOLAO, M. Desenvolvimento de software I: conceitos bá- sicos. Porto Alegre: Bookman, 2014. 236 p. (Série Tekne; Eixo Informação e Comunicação). NICOLETTI, M. C. A cartilha Prolog. São Carlos: Edufscar, 2003. 124 p. (Série Apontamentos). PINHEIRO, F. A. C. Elementos de programação em C: em conformidade com o padrão ISO / IEC 9899. Porto Alegre: Bookman, 2012. 548 p. SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman, 2018. 758 p. Programação orientada a objetos: herança e polimorfismo12 DICA DO PROFESSOR Existem dois tipos básicos de implementação do conceito de polimorfismo em linguagens orientadas a objetos. Pode ser usado o formato de implementação estática ou sobrecarga de métodos ou então o formato de implementação dinâmica ou sobrescrita de método. Qualquer um dos formatos é encontrado. Nesta Dica do Professor, você irá entender o conceito de polimorfismo para que seja possível diferenciar cada um dos seus tipos de implementação. Conteúdo interativo disponível na plataforma de ensino! EXERCÍCIOS 1) Ao analisar um modelo de classes de um sistema, você identificou que existe um relacionamento de herança entre as classes MeioPagamento e CartaoCredito, sendo a classe mãe a MeioPagamento e a classe herdeira a CartaoCredito. Sobre essa situação, assinale a alternativa correta: A) Somente atributos public da classe MeioPagamento serão herdados pela classe CartaoCredito. B) Todos os atributos da classe MeioPagamento serão herdados pela classe CartaoCredito. C) Todos os atributos serão herdados da classe MeioPagamento, mas os métodos não serão. D) Todos os atributos serão herdados, mas novos atributos inseridos na classe MeioPagamento não serão. E) Não será possível criar um objeto a partir da classe CartaoCredito sem antes criar objeto MeioPagamento. 2) Utilizando ainda o exemplo do exercício anterior, caso existisse a necessidade de inserir um atributo para armazenar o valor do limite de gastos diários, que seria único por CartaoCredito, lembrando que a classe MeioPagamento também tem como herdeira a classe CartaoDebito, assinale a alternativa correta sobre essa implementação: A) O atributo limiteGastosDiario seria criado somente na classe CartaoCredito. B) O atributo limiteGastosDiario seria criado na classe CartaoCredito e MeioPagamento. C) O atributo limiteGastosDiario seria criado somente na classe MeioPagamento D) O atributo limiteGastosDiario seria criado na classe MeioPagamento, CartaoCredito e CartaoDebito. E) O atributo limiteGastosDiario seria criado na classe MeioPagamento e CartaoCredito, mas os métodos get e set somente na MeioPagamento. 3) Em algumas linguagens de programação orientada a objetos, como C++ e Python, é possível que uma classe possua relacionamento de herança com mais de uma classe. Assinale a alternativa correta quanto ao nome desse tipo de herança: A) Herança Composta. B) Herança Associativa. C) Herança Dupla. D) Herança Múltipla. E) Herança Binária. 4) Em herança entre classes, existe a possibilidade de uma classe herdeira reescrever um método implementado pela classe mãe. Dessa forma, a classe herdeira atribui um comportamento diferenciado ao da classe mãe, sendo o nome desse conceito polimorfismo. Assinale a alternativa correta sobre o polimorfismo: A) Só é possível aplicar polimorfismo quando os métodos têm a mesma assinatura. B) O polimorfismo é um recurso mais recente que a herança na orientação a objetos. C) Em herança múltipla, não é possível aplicar o conceito de polimorfismo, apenas em herança simples. D) O polimorfismo só permite a alteração de escopo de um método da superclasse pela subclasse. E) O polimorfismo é uma característica em orientação a objetos que usa a hierarquia de objetos. 5) Existem duas formas de implementação de polimorfismo. Uma se dá quando se tem a mesma operação implementada várias vezes na mesma classe e a outra acontece na herança, quando a classe herdeira altera o método original. Assinale a alternativa correta quanto ao nome desses tipos de implementação de polimorfismo: A) Sobrecarga e Sobreposição. B) Estático e Sobrecarga. C) Dinâmico e Sobreposição. D) Alternativo e Sobrecarga. E) Alternativo e Sobreposição. NA PRÁTICA A herança, o polimorfismo e a reutilização de código estão relacionados em programação orientada a objetos. Quando se fala de herança entre classes, fala-se implicitamente de reutilização de código, pois herdar é minimizar a escrita de código. O polimorfismo entra como recurso interessanteque permite que apenas aqueles métodos que devem se comportar de forma diferenciada em uma classe herdeira sejam reescritos sem a necessidade de reescrita total de uma classe. A herança é um conceito muito poderoso, uma vez possibilitar que os desenvolvedores maximizem o uso dos métodos (comportamento) e dos dados (estrutura) dos objetos existentes. Já o polimorfismo é a habilidade de objetos receberem a mesma mensagem e comportarem-se de maneira diferente. Neste Na Prática, você verá um exemplo da utilização de herança e polimorfismo em uma aplicação escrita em Java para entender como esses conceitos se relacionam com o objetivo de reduzir a necessidade de reescrita de código. SAIBA MAIS Para ampliar o seu conhecimento a respeito desse assunto, veja abaixo as sugestões do professor: Herança na programação orientada a objetos Neste vídeo, você entenderá, de forma bem didática, sobre o conceito de herança na programação orientada a objetos. Conteúdo interativo disponível na plataforma de ensino! Conceituando polimorfismo Para conhecer mais sobre o conceito de polimorfismo na programação orientada a objetos, assista ao vídeo a seguir. Conteúdo interativo disponível na plataforma de ensino! Herança Múltipla com Python Assista ao vídeo a seguir e conheça a aplicação do conceito de Herança Múltipla, utilizada na linguagem de programação Python. Conteúdo interativo disponível na plataforma de ensino!
Compartilhar