POO: Polimorfisme

De Cacauet Wiki
Salta a la navegació Salta a la cerca

El polimorfisme és una important propietat de la POO, molt rellevant sobretot en llenguatges on no hi ha tipus dinàmics com el C++ o el Java. El què significa és que una referència (punter) a un objecte genèric (pare), al cridar a una funció que està sobrescrita per un objecte derivat, executarà la funció més "nova", és a dir, la de l'objecte instanciat realment.

El cas típic és tenir un array de punters a objectes pare que no sabem de quin tipus derivat exactament son, per exemple, un array de Pilotes. Segons com l'haguem creat, el punters apuntaran a objectes dels tiups PilotaDeTennis, PilotaDeFutbol i PilotaDeBasket, però no tenim perquè saber-ho, tot i que sabem segur que tots hereden de Pilota. Quan cridem al mètode accelera() s'executarà el de l'objecte derivat, no el del pare genèric, encara que el punter apunti a Pilota.


Polimorfisme en Python

El cas del Python torna a ser una mica "especial". Els avantatges del polimorfisme hi son presents, però estan implícits en el tipus de dades dinàmics i la introspecció. Això vol dir que en tot moment sabem de quin tipus és cada objecte. A sobre, en Python podem tenir arrays o llistes d'objectes heterogenis, cosa que no es pot fer amb Java o C++. Així, el polimorfisme en aquests llenguatges és molt important i va resultar una revolució en la programació, però en llenguatges com Python aquesta funcionalitat ens arriba per unes altres vies.


Exemple de polimorfisme en C++

Repetim l'exemple de la Pilota i l'objecte derivat PilotaDeTennis. Podeu veure que l'objecte derivat sobreescriu la funció accelera. Si aquesta s'ha definit com a "virtual" (i això es important), la funció que s'executarà serà la més derivada possible (en aquest cas, la corresponent a la de la Pilota de Tennis):

#include <stdio.h>

class Pilota 
{
public:
	int posx;
	int posy;
	int velocitat;
	virtual int accelera() {
		velocitat += 5;
	}
	Pilota() {
		posx=10;
		posy=20;
		velocitat=10;
	}
};

class PilotaDeTennis : public Pilota
{
	int color;
	int accelera() {
		velocitat += 12;
	};
};

int main(void)
{
	Pilota p;
	PilotaDeTennis pt;
	Pilota *a[5];

	a[0] = &p;
	a[1] = &pt;

	a[0]->accelera();
	a[1]->accelera();

	printf("vel0=%d  vel1=%d\n",a[0]->velocitat,a[1]->velocitat);
}

Per compilar-lo i executar-ho podem fer:

$ g++ pilotes.c
$ ./a.out
vel0=15  vel1=22

Podem veure que l'element [1] de l'array (PilotaDeTennis) s'ha accelerat diferent de l'element [0] (Pilota).