O que é polimorfismo em C ++?
Em C ++, o polimorfismo faz com que uma função de membro se comporte de maneira diferente com base no objeto que a chama / invoca. Polimorfismo é uma palavra grega que significa ter muitas formas. Ocorre quando você tem uma hierarquia de classes relacionadas por herança.
Por exemplo, suponha que temos a função makeSound (). Quando um gato chama essa função, ele produz o som de miado. Quando uma vaca invoca a mesma função, ela emitirá o som de moow.
Embora tenhamos uma função, ela se comporta de maneira diferente em diferentes circunstâncias. A função tem muitas formas; portanto, alcançamos o polimorfismo.
Neste tutorial C ++, você aprenderá:
- O que é polimorfismo?
- Tipos de polimorfismo
- Polimorfismo de tempo de compilação
- Sobrecarga de função
- Sobrecarga do operador
- Polimorfismo de tempo de execução
- Substituição de função
- Função Virtual C ++
- Polimorfismo de tempo de compilação vs. Polimorfismo de tempo de execução
Tipos de polimorfismo
C ++ suporta dois tipos de polimorfismo:
- Polimorfismo de tempo de compilação e
- Polimorfismo de tempo de execução.
Polimorfismo de tempo de compilação
Você invoca as funções sobrecarregadas combinando o número e o tipo de argumentos. A informação está presente durante o tempo de compilação. Isso significa que o compilador C ++ selecionará a função correta no momento da compilação.
O polimorfismo de tempo de compilação é obtido por meio de sobrecarga de função e sobrecarga do operador.
Sobrecarga de função
A sobrecarga de função ocorre quando temos muitas funções com nomes semelhantes, mas argumentos diferentes. Os argumentos podem diferir em termos de número ou tipo.
Exemplo 1:
#includeusing namespace std;void test(int i) {cout << " The int is " << i << endl;}void test(double f) {cout << " The float is " << f << endl;}void test(char const *ch) {cout << " The char* is " << ch << endl;}int main() {test(5);test(5.5);test("five");return 0;}
Resultado:
Aqui está uma captura de tela do código:
Explicação do código:
- Inclua o arquivo de cabeçalho iostream em nosso código. Poderemos usar suas funções.
- Inclua o namespace std em nosso código. Poderemos usar suas classes sem chamá-lo.
- Crie uma função chamada test que tenha um parâmetro inteiro i. O {marca o início do corpo do teste de função.
- Instrução a ser executada se o teste de função acima for invocado / chamado.
- Fim do corpo do teste de função acima.
- Crie uma função chamada test que tenha um parâmetro float f. O {marca o início do corpo do teste de função.
- Instrução a ser executada se o teste de função acima for invocado / chamado.
- Fim do corpo do teste de função acima.
- Crie uma função chamada test que tenha um parâmetro de caractere ch. O {marca o início do corpo do teste de função.
- Instrução a ser executada se o teste de função acima for invocado / chamado.
- Fim do corpo do teste de função acima.
- Chame a função main (). O {marca o início do corpo da função.
- Chame a função test e passe 5 para ele como o valor do argumento. Isso invoca a função de teste que aceita um argumento inteiro, ou seja, a primeira função de teste.
- Chame a função test e passe 5.5 para ela como o valor do argumento. Isso invocará a função de teste que aceita um argumento float, ou seja, a segunda função de teste.
- Chame a função test e passe cinco para ele como o valor do argumento. Isso invocará a função de teste que aceita um argumento de caractere, ou seja, a terceira função de teste.
- O programa deve retornar um valor se for executado com êxito.
- O final do corpo da função main ().
Temos três funções com o mesmo nome, mas diferentes tipos de argumentos. Conseguimos polimorfismo.
Sobrecarga do operador
Em Operator Overloading, definimos um novo significado para um operador C ++. Também muda a forma como o operador trabalha. Por exemplo, podemos definir o operador + para concatenar duas strings. Nós o conhecemos como o operador de adição para adicionar valores numéricos. Após nossa definição, quando colocado entre inteiros, ele os adicionará. Quando colocado entre strings, ele os concatenará.
Exemplo 2:
#includeusing namespace std;class ComplexNum {private:int real, over;public:ComplexNum(int rl = 0, int ov = 0) {real = rl;over = ov;}ComplexNum operator + (ComplexNum const &obj) {ComplexNum result;result.real = real + obj.real;result.over = over + obj.over;return result;}void print() {cout << real << " + i" << over << endl;}};int main(){ComplexNum c1(10, 2), c2(3, 7);ComplexNum c3 = c1+c2;c3.print();}
Resultado:
Aqui está uma captura de tela do código:
Explicação do código:
- Inclua o arquivo de cabeçalho iostream em nosso programa para usar suas funções.
- Inclua o namespace std em nosso programa para usar suas classes sem chamá-lo.
- Crie uma classe chamada ComplexNum. O {marca o início do corpo da classe.
- Use o modificador de acesso privado para marcar variáveis como privadas, o que significa que elas só podem ser acessadas de dentro da classe.
- Defina duas variáveis inteiras, reais e superiores.
- Use o modificador de acesso público para marcar o construtor como público, o que significa que ele estará acessível mesmo de fora da classe.
- Crie o construtor da classe e inicialize as variáveis.
- Inicialize o valor da variável real.
- Inicialize o valor da variável.
- Fim do corpo do construtor.
- Precisamos substituir o significado do operador +.
- Crie o resultado do tipo de dados do tipo ComplexNum.
- Use o operador + com números complexos. Esta linha adicionará a parte real de um número à parte real de outro número.
- Use o operador + com números complexos. Esta linha adicionará a parte imaginária de um número à parte imaginária de outro número.
- O programa retornará o valor do resultado variável após a execução bem-sucedida.
- Fim da definição do novo significado do operador +, ou seja, sobrecarga.
- Chame o método print ().
- Imprima o novo número complexo após a adição no console.
- Fim do corpo da função print ().
- Fim do corpo da classe ComplexNum.
- Chame a função main ().
- Passe os valores das partes reais e complexas a serem adicionadas. A primeira parte de c1 será adicionada à primeira parte de c2, ou seja, 10 + 3. A segunda parte de c1 será adicionada à segunda parte de c, ou seja, 2 + 7.
- Execute uma operação usando o operador sobrecarregado + e armazenando o resultado na variável c3.
- Imprima o valor da variável c3 no console.
- Fim do corpo da função main ().
Polimorfismo de tempo de execução
Isso acontece quando o método de um objeto é invocado / chamado durante o tempo de execução e não durante o tempo de compilação. O polimorfismo de tempo de execução é obtido por meio da substituição de função. A função a ser chamada / invocada é estabelecida durante o tempo de execução.
Substituição de função
A substituição de função ocorre quando uma função da classe base recebe uma nova definição em uma classe derivada. Nesse momento, podemos dizer que a função base foi substituída.
Por exemplo:
#includeusing namespace std;class Mammal {public:void eat() {cout << "Mammals eat… ";}};class Cow: public Mammal {public:void eat() {cout << "Cows eat grass… ";}};int main(void) {Cow c = Cow();c.eat();return 0;}
Resultado:
Aqui está uma captura de tela do código:
Explicação do código:
- Importe o arquivo de cabeçalho iostream em nosso programa para usar suas funções.
- Inclua o namespace std em nosso programa para usar suas classes sem chamá-lo.
- Crie uma classe chamada Mammal. O {marca o início do corpo da classe.
- Use o modificador de acesso público para definir a função que estamos prestes a criar como acessível publicamente. Estará acessível fora desta classe.
- Crie uma função pública chamada comer. O {marca o início do corpo da função.
- Imprime a instrução adicionada à função cout quando a função eat () é chamada.
- O fim do corpo da função eat ().
- Fim do corpo da classe Mamíferos.
- Crie uma classe chamada Cow que herda a classe Mammal. Cow é a classe derivada, enquanto Mammal é a classe base. O {marca o início desta aula.
- Use o modificador de acesso público para marcar a função que estamos prestes a criar como acessível publicamente. Estará acessível fora desta classe.
- Substitua a função eat () que foi definida na classe base. O {marca o início do corpo da função.
- A instrução a ser impressa no console quando esta função é chamada.
- Fim do corpo da função eat ().
- Fim do corpo da classe Vaca.
- Chame a função main (). O {marca o início do corpo desta função.
- Crie uma instância da classe Cow e dê a ela o nome c.
- Chame a função eat () definida na classe Cow.
- O programa deve retornar um valor após a conclusão bem-sucedida.
- Fim da função main ().
Função Virtual C ++
Uma função virtual é outra maneira de implementar polimorfismo de tempo de execução em C ++. É uma função especial definida em uma classe base e redefinida na classe derivada. Para declarar uma função virtual, você deve usar a palavra-chave virtual. A palavra-chave deve preceder a declaração da função na classe base.
Se uma classe de função virtual for herdada, a classe virtual redefine a função virtual para atender às suas necessidades. Por exemplo:
#includeusing namespace std;class ClassA {public:virtual void show() {cout << "The show() function in base class invoked… " << endl;}};class ClassB :public ClassA {public:void show() {cout << "The show() function in derived class invoked… ";}};int main() {ClassA* a;ClassB b;a = &b;a->show();}
Resultado:
Aqui está uma captura de tela do código:
Explicação do código:
- Inclua o arquivo de cabeçalho iostream no código para usar suas funções.
- Inclua o namespace std em nosso código para usar suas classes sem chamá-lo.
- Crie uma classe chamada ClassA.
- Use o modificador de acesso público para marcar um membro da classe como acessível publicamente.
- Crie uma função virtual chamada show (). Será uma função pública.
- O texto a ser impresso quando o show () invocado é invocado. O endl é uma palavra-chave C ++, que significa linha final. Ele move o cursor do mouse para a próxima linha.
- Fim do corpo da função virtual show ().
- Fim do corpo da classe ClassA.
- Criando uma nova classe chamada ClassB que herda a classe ClassA. ClassA se torna a classe base enquanto ClassB se torna a classe derivada.
- Use o modificador de acesso público para marcar um membro da classe como acessível publicamente.
- Redefina a função virtual show () derivada da classe base.
- O texto a ser impresso no console quando a função show () definida na classe derivada é chamada.
- Fim do corpo da função show ().
- Fim do corpo da classe derivada, ClassB.
- Chame a função main (). A lógica do programa deve ser adicionada em seu corpo.
- Crie uma variável de ponteiro chamada a. Ele aponta para a classe chamada ClassA.
- Crie uma instância da classe chamada ClassB. A instância recebe o nome de b.
- Atribua os armazenamentos de valores no endereço b na variável a.
- Invoque a função show () definida na classe derivada. A vinculação tardia foi implementada.
- Fim do corpo da função main ().
Polimorfismo de tempo de compilação vs. Polimorfismo de tempo de execução
Aqui estão as principais diferenças entre os dois:
Polimorfismo de tempo de compilação | Polimorfismo de tempo de execução |
Também é chamado de ligação inicial ou polimorfismo estático | Também é chamado de ligação tardia / dinâmica ou polimorfismo dinâmico |
O método é chamado / invocado durante o tempo de compilação | O método é chamado / invocado durante o tempo de execução |
Implementado por meio de sobrecarga de função e sobrecarga do operador | Implementado por meio de substituição de método e funções virtuais |
Exemplo, sobrecarga de método. Muitos métodos podem ter nomes semelhantes, mas diferentes números ou tipos de argumentos | Exemplo, substituição de método. Muitos métodos podem ter um nome semelhante e o mesmo protótipo. |
Execução mais rápida uma vez que a descoberta dos métodos é feita durante o tempo de compilação | Execução mais lenta, pois o descobridor de método é feito durante o tempo de execução. |
Menos flexibilidade para a resolução de problemas é fornecida, uma vez que tudo é conhecido durante o tempo de compilação. | Muita flexibilidade é fornecida para resolver problemas complexos, uma vez que os métodos são descobertos durante o tempo de execução. |
Resumo:
- Polimorfismo significa ter muitas formas.
- Ocorre quando existe uma hierarquia de classes relacionadas por herança.
- Com o polimorfismo, uma função pode se comportar de maneira diferente com base no objeto que a invoca / chama.
- No polimorfismo em tempo de compilação, a função a ser chamada é estabelecida durante o tempo de compilação.
- No polimorfismo de tempo de execução, a função a ser chamada é estabelecida durante o tempo de execução.
- O polimorfismo de tempo de compilação é determinado por meio de sobrecarga de função e sobrecarga do operador.
- Na sobrecarga de função, existem muitas funções com nomes semelhantes, mas argumentos diferentes.
- Os parâmetros podem diferir em número ou tipo.
- Na sobrecarga de operador, um novo significado é definido para operadores C ++.
- O polimorfismo de tempo de execução é obtido por meio da substituição de função.
- Na substituição de função, uma classe derivada fornece uma nova definição para uma função definida na classe base.