El polimorfisme és un concepte fonamental en la programació orientada a objectes (POO) que permet que una interfície única representi diferents tipus d'objectes. En C++, el polimorfisme es pot aconseguir principalment mitjançant funcions virtuals i herència. Aquest mòdul explorarà els conceptes clau del polimorfisme, com implementar-lo i com utilitzar-lo de manera efectiva.
Conceptes Clau
-
Polimorfisme en Temps de Compilació vs. Polimorfisme en Temps d'Execució:
- Polimorfisme en Temps de Compilació: També conegut com a polimorfisme estàtic, es refereix a la sobrecàrrega de funcions i operadors.
- Polimorfisme en Temps d'Execució: També conegut com a polimorfisme dinàmic, es refereix a l'ús de funcions virtuals i herència per permetre que una funció es comporti de manera diferent segons l'objecte que la crida.
-
Funcions Virtuals:
- Les funcions virtuals permeten que una funció definida en una classe base sigui sobreescrita per una funció amb la mateixa signatura en una classe derivada.
-
Classes Abstractes i Funcions Pures Virtuals:
- Una classe abstracta és una classe que no es pot instanciar i que sovint conté una o més funcions pures virtuals. Una funció pura virtual és una funció que es defineix amb
= 0
i ha de ser sobreescrita en una classe derivada.
- Una classe abstracta és una classe que no es pot instanciar i que sovint conté una o més funcions pures virtuals. Una funció pura virtual és una funció que es defineix amb
Exemples Pràctics
Exemple 1: Funcions Virtuals
#include <iostream> using namespace std; class Animal { public: virtual void makeSound() { cout << "Some generic animal sound" << endl; } }; class Dog : public Animal { public: void makeSound() override { cout << "Woof!" << endl; } }; class Cat : public Animal { public: void makeSound() override { cout << "Meow!" << endl; } }; int main() { Animal* animal1 = new Dog(); Animal* animal2 = new Cat(); animal1->makeSound(); // Output: Woof! animal2->makeSound(); // Output: Meow! delete animal1; delete animal2; return 0; }
Explicació
-
Classe Base
Animal
:- Conté una funció virtual
makeSound()
que es pot sobreescriure en classes derivades.
- Conté una funció virtual
-
Classes Derivades
Dog
iCat
:- Sobrecarreguen la funció
makeSound()
per proporcionar una implementació específica.
- Sobrecarreguen la funció
-
Polimorfisme en Temps d'Execució:
- En el
main()
, es creen objectes deDog
iCat
però es tracten com a objectes de tipusAnimal
. Quan es cridamakeSound()
, s'executa la versió correcta de la funció segons el tipus real de l'objecte.
- En el
Exemple 2: Classes Abstractes i Funcions Pures Virtuals
#include <iostream> using namespace std; class Shape { public: virtual void draw() = 0; // Funció pura virtual }; class Circle : public Shape { public: void draw() override { cout << "Drawing Circle" << endl; } }; class Square : public Shape { public: void draw() override { cout << "Drawing Square" << endl; } }; int main() { Shape* shape1 = new Circle(); Shape* shape2 = new Square(); shape1->draw(); // Output: Drawing Circle shape2->draw(); // Output: Drawing Square delete shape1; delete shape2; return 0; }
Explicació
-
Classe Abstracta
Shape
:- Conté una funció pura virtual
draw()
, la qual cosa fa queShape
sigui una classe abstracta.
- Conté una funció pura virtual
-
Classes Derivades
Circle
iSquare
:- Implementen la funció
draw()
.
- Implementen la funció
-
Polimorfisme en Temps d'Execució:
- En el
main()
, es creen objectes deCircle
iSquare
però es tracten com a objectes de tipusShape
. Quan es cridadraw()
, s'executa la versió correcta de la funció segons el tipus real de l'objecte.
- En el
Exercicis Pràctics
Exercici 1: Implementar Polimorfisme
Crea una classe base Vehicle
amb una funció virtual move()
. Després, crea dues classes derivades Car
i Bicycle
que sobrecarreguin la funció move()
per proporcionar una implementació específica. Finalment, crea un programa que utilitzi polimorfisme per cridar la funció move()
en objectes de tipus Vehicle
.
Solució
#include <iostream> using namespace std; class Vehicle { public: virtual void move() = 0; // Funció pura virtual }; class Car : public Vehicle { public: void move() override { cout << "Car is moving" << endl; } }; class Bicycle : public Vehicle { public: void move() override { cout << "Bicycle is moving" << endl; } }; int main() { Vehicle* vehicle1 = new Car(); Vehicle* vehicle2 = new Bicycle(); vehicle1->move(); // Output: Car is moving vehicle2->move(); // Output: Bicycle is moving delete vehicle1; delete vehicle2; return 0; }
Consells i Errors Comuns
-
No oblidis el
virtual
:- Assegura't de declarar les funcions com a
virtual
en la classe base per permetre el polimorfisme en temps d'execució.
- Assegura't de declarar les funcions com a
-
Destructors Virtuals:
- Si una classe conté funcions virtuals, és una bona pràctica declarar el destructor com a virtual per assegurar una correcta neteja de recursos.
-
Classes Abstractes:
- Recorda que no pots instanciar una classe abstracta directament. Només pots crear objectes de les seves classes derivades.
Resum
En aquesta secció, hem après sobre el polimorfisme en C++, incloent-hi el polimorfisme en temps de compilació i en temps d'execució. Hem explorat com utilitzar funcions virtuals i classes abstractes per implementar polimorfisme i hem vist exemples pràctics per il·lustrar aquests conceptes. A més, hem proporcionat exercicis per reforçar l'aprenentatge i consells per evitar errors comuns. Amb aquests coneixements, estàs preparat per aplicar el polimorfisme en els teus projectes de C++.
Curs de Programació en C++
Mòdul 1: Introducció al C++
- Introducció al C++
- Configuració de l'Entorn de Desenvolupament
- Sintaxi i Estructura Bàsica
- Variables i Tipus de Dades
- Entrada i Sortida
Mòdul 2: Estructures de Control
Mòdul 3: Funcions
- Introducció a les Funcions
- Paràmetres de Funció i Tipus de Retorn
- Sobrecàrrega de Funcions
- Recursivitat
Mòdul 4: Arrays i Strings
Mòdul 5: Punteres i Referències
- Introducció als Punteres
- Aritmètica de Punteres
- Punteres i Arrays
- Referències
- Assignació Dinàmica de Memòria
Mòdul 6: Programació Orientada a Objectes
- Introducció a la POO
- Classes i Objectes
- Constructors i Destructors
- Herència
- Polimorfisme
- Encapsulació i Abstracció
Mòdul 7: Temes Avançats
- Plantilles
- Gestió d'Excepcions
- Entrada/Sortida de Fitxers
- Biblioteca de Plantilles Estàndard (STL)
- Expressions Lambda
- Multifil