Polimorfismo vs. Herança: Diferença entre Polimorfismo e Herança [2022]

Publicados: 2021-01-05

Polimorfismo e herança são conceitos fundamentais da programação orientada a objetos. A adição de objetos nas linguagens de programação modernas fez uma diferença considerável na maneira como usamos a linguagem e nas coisas que somos capazes de fazer com eles. Em poucas palavras, a programação orientada a objetos é um conjunto de métodos que permite ao programador usar classes e, portanto, derivar objetos com base nessas classes.

Ele visa se assemelhar a entidades do mundo real e tornar mais fácil para os programadores tornarem seu código inclusivo do paradigma no qual estão escrevendo seu código. Existem essencialmente quatro conceitos de programação orientada a objetos, a saber, Herança, Abstração, Polimorfismo e encapsulamento. Agora, cada uma das ideias, como mencionado anteriormente, pode ser pensada como os pilares sobre os quais qualquer linguagem moderna se sustenta.

Voltando ao nosso tópico de polimorfismo versus herança e direito do bastão, vemos uma diferença gritante entre os dois conceitos. Herança é o conceito que permite que o código seja reutilizado novamente no mesmo programa ou em outro. Podemos até mudar o comportamento do código mantendo as coisas que gostamos e descartando as que não são úteis para as tarefas que estamos tentando realizar. A herança economiza muito tempo no desenvolvimento de quase tudo que vemos em nossos displays digitais hoje em dia.

Por outro lado, o polimorfismo é responsável por ditar o código que já foi escrito e decidir que tipo de código precisa ser executado com base em parâmetros específicos em tempo real. Seria benéfico para qualquer um passar primeiro por cada um desses conceitos em detalhes, antes de avançar para a discussão da diferença entre polimorfismo e herança. As diferenças se tornarão mais pronunciadas quando soubermos o que exatamente significa Herança e Polimorfismo.

Obtenha diplomas de Engenharia de Software das melhores universidades do mundo. Ganhe Programas PG Executivos, Programas de Certificado Avançado ou Programas de Mestrado para acelerar sua carreira.

Índice

Herança

Seria um crime no paradigma da programação não considerar a herança como um conceito de POO altamente crucial. A importância da herança nunca deve ser tratada levianamente porque o objetivo da herança é a “reutilização”. O que a herança faz, como o nome sugere, é que ela permite que o código escrito em uma classe seja estendido para outra classe. Assim, na herança, existe uma classe base; a classe na qual o código é escrito deve ser reutilizada.

A próxima classe que criaríamos teria que ser herdada dessa classe base para usar todas as funções e variáveis ​​associadas à classe base. Sempre que uma classe recebe as propriedades de outra classe (ou herda de uma classe diferente), todos os membros presentes na classe base tornam-se membros dessa nova classe derivada.

O código de exemplo abaixo mostra como é uma forma geral de herança. Uma coisa importante a ser observada aqui é que a sintaxe exata que você teria que escrever para habilitar a herança do seu código dependeria apenas da linguagem de programação que você escolher.

  1. class derivado-class-name : access-specifier base-class-name{
  2. // corpo da classe derivada
  3. }

No exemplo mostrado acima, certas coisas precisam de uma pequena explicação. A palavra “especificador de acesso” significa a maneira pela qual a classe derivada acessaria as propriedades e métodos da classe base. Existem três especificadores de acesso em geral, cada um com seu próprio significado (ou seja, privado, público e protegido) e propriedades.

Mais uma vez, dependendo do idioma de sua escolha, você pode ou não ter que usar esses especificadores de acesso. Então, no mundo do C++, se você herdar sem especificar nada por padrão, ele se torna privado. No entanto, se você herdar de uma estrutura (passa pela palavra-chave struct), o especificador de acesso padrão seria público em vez de privado.

Leia: Oportunidades de Carreira na Linguagem de Programação R

O C++ também oferece muitas opções para você escolher quando estiver fazendo herança. Você encontrará alguns deles listados abaixo:

uma. Herança Hierárquica: Este tipo de herança segue a regra de que deve haver apenas uma superclasse, e dessa superclasse, deve haver muitas subclasses derivadas. Você encontrará um exemplo disso abaixo:

  1. //Classe básica
  2. classe A
  3. {
  4. public void funA()
  5. {
  6. //
  7. }
  8. }
  9. //Classe derivada
  10. classe B: A
  11. {
  12. public void funB()
  13. {
  14. //
  15. }
  16. }
  17. //Classe derivada
  18. classe C: A
  19. {
  20. public void funC()
  21. {
  22. //
  23. }
  24. }
  25. //Classe derivada
  26. classe D: C
  27. {
  28. public void funD()
  29. {
  30. //
  31. }
  32. }
  33. //Classe derivada
  34. classe E: C
  35. {
  36. public void funE()
  37. {
  38. //
  39. }
  40. }
  41. //Classe derivada
  42. classe F: B
  43. {
  44. public void funF()
  45. {
  46. //
  47. }
  48. }
  49. //Classe derivada
  50. classe G: B
  51. {
  52. public void funG()
  53. {
  54. //
  55. }
  56. }

b. Herança múltipla: Se você estiver fazendo herança múltipla, isso significaria que você tem apenas uma subclasse derivada que está herdando de várias superclasses. Você encontrará um exemplo simples de herança múltipla abaixo:

  1. //Classe básica
  2. classe A
  3. {
  4. public void funA()
  5. {
  6. //
  7. }
  8. }
  9. //Classe básica
  10. classe B
  11. {
  12. public void funB()
  13. {
  14. //
  15. }
  16. }
  17. //Classe derivada
  18. classe C: A, B
  19. {
  20. public void funC()
  21. {
  22. //
  23. }
  24. }

c. Herança Única: Esta é talvez a forma mais simples de herança. Existe apenas uma classe base e uma classe derivada. Você encontrará um exemplo abaixo:

  1. //Classe básica
  2. classe A
  3. {
  4. public void funA()
  5. {
  6. //FAÇAM:
  7. }
  8. }
  9. //Classe derivada
  10. classe B: A
  11. {
  12. public void funB()
  13. {
  14. //FAÇAM:
  15. }
  16. }

Polimorfismo

A definição básica da palavra polimorfismo significa ter muitas formas. Esta definição é muito precisa para explicar o polimorfismo no contexto da programação. Neste paradigma, o polimorfismo assume o significado de uma função, mas muitas formas. O polimorfismo realmente acontece em tempo de compilação. O polimorfismo em tempo de compilação só é possível devido ao conceito de sobrecarga e, em tempo de execução, o recurso de substituição torna o polimorfismo uma realidade. Um por um, vamos abordar a definição de sobrecarga e sobreposição.

A sobrecarga requer que o código que você escreve ou a função da classe seja escrita mais de uma vez com parâmetros diferentes, mas com o mesmo tipo de retorno. Isso significa que os argumentos que você passa para a função podem ser diferentes, e apenas observando os valores finais que são passados ​​para a função em tempo de execução, qual forma da função deve ser chamada é decidida. Geralmente, vemos o construtor da classe ser a função mais sobrecarregada. Toda essa teoria ficará muito clara e será mais fácil para você enraizá-la em sua mente com a ajuda de um exemplo.

  1. sobrecarga de classe{
  2. int a, b;
  3. público:
  4. int sobrecarga (int x){ // primeiro construtor de sobrecarga()
  5. a=x;
  6. retornar um;
  7. }
  8. int sobrecarga (int x, int y){ //segundo construtor de sobrecarga()
  9. a=x;
  10. b=y;
  11. retornar a*b;
  12. }
  13. };
  14. int main (){
  15. sobrecarga O1;
  16. O1. sobrecarga (20); //primeira chamada do construtor de sobrecarga()
  17. O1. sobrecarga (20,40); // segunda chamada do construtor de sobrecarga()

Aqui neste exemplo, vemos a sobrecarga em ação. Veja como diferentes construtores são chamados dependendo se o valor final do parêntese do objeto é um inteiro ou dois.

Vamos abordar a definição de Overriding a seguir. Você só pode substituir as funções específicas que são herdadas. Sim, a herança é um ponto-chave para tornar possível a substituição de funções. Se você quiser escrever uma função e também substituí-la, em C++ você terá que usar a palavra-chave virtual antes da definição da função, e na classe derivada usando o mesmo nome para sua função, basta remover a palavra-chave virtual. Para solidificar sua compreensão, aqui está um exemplo:

  1. base de classe{
  2. público:
  3. virtual void funct (){ //função virtual da classe base
  4. cout<<“Esta é uma função da classe base()”;
  5. }
  6. };
  7. classe derivada1: base pública{
  8. público:
  9. void funct (){ //função virtual da classe base redefinida na classe derivada1
  10. cout<<“Esta é a função de uma classe derivada1”;
  11. }
  12. };
  13. int principal ()
  14. {
  15. base *p, b;
  16. derivado1 d1;
  17. *p=&b;
  18. p-> função (); //chama a classe base funct().
  19. *p=&d1;
  20. retornar 0;
  21. }

Veja como a palavra-chave virtual é usada na classe base e, na classe derivada, a mesma definição de função existe apenas a palavra-chave virtual está ausente.

Algumas diferenças entre polimorfismo e herança:

  1. Herança é essencialmente criar uma classe e, em seguida, fazer com que outras classes em seu programa obtenham seus recursos da classe base já existente. No entanto, o polimorfismo é uma interface e, por ser uma interface, pode assumir diferentes formas e formatos.
  2. A herança é uma propriedade pertencente apenas a classes, enquanto o polimorfismo se estende a qualquer método e/ou função.
  3. A herança permite que a classe derivada use todas as funções e variáveis ​​declaradas na classe base sem defini-las explicitamente novamente. É por isso que dizemos que a herança aumenta a reutilização do código e reduz o comprimento do código, que teríamos que escrever se a herança estivesse ausente. Considerando que, o polimorfismo permite que o mesmo nome de função tenha dois códigos muito diferentes. Então, em certo sentido, em vez de reduzir o tamanho do código que teríamos que escrever, o polimorfismo o está estendendo ainda mais.
  4. Há muitas formas que a herança pode assumir; você pode ser realmente criativo com herança. No entanto, o polimorfismo só pode ser realizado por dois meios, ou seja, sobrecarga e sobreposição. Você ainda pode enlouquecer ao usar o polimorfismo, mas está restrito a apenas duas maneiras de implementá-lo em seu código de escrita.

Deve ler: Deve ler 47 perguntas e respostas da entrevista OOPS para calouros e experientes

Polimorfismo vs. herança: diferenciação tabular

Na tabela abaixo, você encontrará uma clara diferença entre polimorfismo e herança:

MEDIDAS COMPARATIVAS HERANÇA POLIMORFISMO
Diferenças fundamentais entre os dois O significado de herança é criar novas classes que possuem propriedades (funções e variáveis ​​das classes existentes) É essencialmente uma plataforma que permite que o código seja escrito em diferentes formas.
Diferenças na maneira como ambos podem ser integrados ao seu código Apenas classes podem desfrutar de herança real no código. Ele pode ser implementado e usado por quaisquer funções e/ou métodos em todo o código.
Diferenças na forma como ambos podem ser usados. Ele permite que o código escrito seja reutilizado dentro do mesmo programa ou de um programa diferente. Sem ele, a programação orientada a objetos perderia um recurso crucial. Ele permite que o objeto declarado tome a decisão de qual forma da função deve ser chamada. Há dois momentos em que isso pode ser decidido. Em tempo de execução, é chamado de substituição; em tempo de compilação, é chamado de sobrecarga.
Diferentes formas, ambos podem assumir Há uma infinidade de formas que a herança pode assumir. Só pode haver duas formas de polimorfismo. Dependendo do tempo no programa, ele muda de sobrecarga para substituição.
Um exemplo básico demonstrando como cada um deles é implementado. A classe bicicleta pode herdar da classe de veículos de duas rodas, que por sua vez pode ser uma subclasse de veículos. A classe bike pode ter um método chamado set_color(), que muda a cor da bike com base no nome da cor que você digitou.

Confira: O que é Type Casting em Java | Entendendo o casting de tipos como iniciante

Conclusão

É seguro dizer que tanto o polimorfismo quanto a herança são conceitos críticos para tornar qualquer programa uma realidade. Ambos são a base sobre a qual a ideia de programação orientada a objetos foi estabelecida. Existem muitas diferenças entre polimorfismo e herança porque eles servem a dois propósitos muito diferentes.

O polimorfismo permite que o programador escreva várias definições de uma função. Ao mesmo tempo, a herança permite que o usuário reutilize o código já escrito. Para entender e apreciar completamente os dois conceitos, é recomendável que você leia mais sobre ambos os tópicos.

Uma coisa que você deve sempre ter em mente sempre que estiver escrevendo código é que se você estiver procurando refatorar o código que você já escreveu (basicamente a definição de uma classe e usá-la novamente em seu código para servir um propósito), você deve fazer uso de herança. Se você deseja reduzir a confusão geral em seu código e deseja usar o mesmo nome da função para realizar tarefas semelhantes, use o polimorfismo.

Se você estiver interessado em aprender mais sobre desenvolvimento de software full-stack, confira o PG Diploma in Full-stack Software Development do upGrad & IIIT-B, projetado para profissionais que trabalham e oferece mais de 500 horas de treinamento rigoroso, mais de 9 projetos e atribuições, status de ex-alunos do IIIT-B, projetos práticos práticos e assistência de trabalho com as principais empresas.

Planeje sua carreira de desenvolvimento de software agora.

Inscreva-se para a Certificação PG vinculada ao trabalho do upGrad em Engenharia de Software