Curso de Extensão: Linguagem de Programação C++ (Básico)


Faculdade de Informática, PUCRS, Porto Alegre, RS

Coordenação: Isabel Harb Manssour


Instrutores: Eduardo Bezerra e Cristiane Woszezenki



Polimorfismo


Polimorfismo é a situação na qual objetos pertencentes a diferentes classes podem responder a uma mesma mensagem, normalmente de maneiras diferentes. Mais exatamente, a capacidade de um objeto assumir diferentes formas. Polimorfismo pode ser utilizado para simplificar, por exemplo, o trabalho para impressão dos valores de nodos em uma lista heterogênea. Em uma lista heterogênea cada nodo pode possuir objetos de classes diferentes, e o polimorfismo simplifica a manipulação desse tipo de lista.


Para implementação de polimorfismo em C++ é necessário um bom conhecimento na manipulação de ponteiros, e também no assunto herança. É recomendável também estar familiarizado com tópicos intermediários, tais como: funções virtuais, funções virtuais puras e classes abstratas. Esses assuntos são objeto estudo em um curso intermediário de C++, fugindo do escopo desse curso básico. De qualquer forma, a seguir é apresentado um exemplo típico de implementação de polimorfismo em C++. No exemplo não foi possível deixar de lado os detalhes relacionados à esses assuntos intermediários do C++, que serão melhor explorados em um curso mais avançado.


Um exemplo mais tradicional de uso de polimorfismo e' representado na figura a seguir.






Diversas raças de cachorros são herdadas da classe “dog” que possui uma função para impressão da raça do objeto “dog” em uso. A função “print_breed” a ser executada será aquela pertencente ao objeto em uso. No programa a seguir um objeto é declarado para cada classe (d, b, c, s, ms, ss, gs). O ponteiro “dp” é criado para apontar para a classe base (Dog). Esse ponteiro apesar de ser do tipo Dog, pode ser utilizado para apontar para as classes derivadas, e no exemplo a seguir as chamadas “dp->printBreed()” acionam as funções virtuais das classes derivadas produzindo a seguinte saída:


Breed not defined

Boxer

Cocker Spaniel

Schnauzer

Miniature Schnauzer

Standard Schnauzer

Giant Schnauzer


O mesmo principio é utilizado a seguir onde “rd”, “rs” e “rm” são referências a objetos “Dog” porém ao atribuir os objetos de classes derivadas a essas referências, o conceito de polimorfismo se torna bastante evidente, pois “Dog” assumirá diversas formas, e as três últimas chamadas ao método “printBreed()” resultarão na seguinte saída:


Breed not defined

Schnauzer

Miniature Schnauzer


Listagem do programa exemplo:


#include <iostream>
using namespace std;

class Dog {
   public:
    virtual void printBreed(){
     cout << "Breed not defined\n";
    }
};
class Boxer : public Dog {
   public:
      void printBreed() {
         cout << "Boxer\n";
      }
};
class Cocker : public Dog {
   public:
      void printBreed() {
        cout << "Cocker Spaniel\n";
      }
};
class Schnauzer : public Dog {
   public: void printBreed() {
             cout << "Schnauzer\n";
           }
};
class MiniatureSchnauzer : 
                 public Schnauzer {
   public:
      void printBreed() {
         cout << "Miniature" << "Schnauzer\n";
      }
};
class StandardSchnauzer :
                 public Schnauzer {
   public:
      void printBreed() {
         cout << "Standard" << "Schnauzer\n";
      }
};

class GiantSchnauzer : public Schnauzer {
   public:
      void printBreed() {
       cout << "Giant Schnauzer\n";
      }
};

int main() {
   Dog d;
   Boxer b;
   Cocker c;
   Schnauzer s;
   MiniatureSchnauzer ms;
   StandardSchnauzer ss;
   GiantSchnauzer gs;

   Dog* dp;
        
   dp = &d; dp->printBreed();
   dp = &b; dp->printBreed();
   dp = &c; dp->printBreed();
   dp = &s; dp->printBreed();
   dp = &ms; dp->printBreed();
   dp = &ss; dp->printBreed();
   dp = &gs; dp->printBreed();

   cout << "\n";

   Dog& rd = d;
   Dog& rs = s;
   Dog& rm = ms;

   rd.printBreed();
   rs.printBreed();
   rm.printBreed();
                
}