b'\n_START_ARTICLE_\nPolimorfisme (programaci\xc3\xb3)\n_START_PARAGRAPH_\nEl polimorfisme (del Grec \xcf\x80\xce\xbf\xce\xbb\xcf\x8d\xcf\x82, polys, "molt, molts" i \xce\xbc\xce\xbf\xcf\x81\xcf\x86\xce\xae, morph\xc4\x93, "forma, figura") \xc3\xa9s una caracter\xc3\xadstica d\'alguns llenguatges de programaci\xc3\xb3 que tenen la propietat d\'enviar missatges sint\xc3\xa0cticament iguals als objectes de diferents tipus. L\'\xc3\xbanic requisit que han de complir els objectes que s\'utilitzen de manera polim\xc3\xb2rfica \xc3\xa9s saber respondre al missatge que se\'ls hi envia. _NEWLINE_L\'aparen\xc3\xa7a dels codi pot ser molt diferent depenent del llenguatge que s\'utilitzi, m\xc3\xa9s enll\xc3\xa0 de les \xc3\xb2bvies difer\xc3\xa8ncies sint\xc3\xa0ctiques._NEWLINE_Hi ha dos tipus gen\xc3\xa8rics de polimorfisme: el polimorfisme de sobre-c\xc3\xa0rrega (overload) i el polimorfisme de sobre-escriptura (override).\n_START_SECTION_\nDescripci\xc3\xb3\n_START_PARAGRAPH_\nEn el llenguatge basat en classes i amb un sistema de tipus de dades fort (independentment de si la verificaci\xc3\xb3 es realitza en temps de compilaci\xc3\xb3 o d\'execuci\xc3\xb3), \xc3\xa9s possible que l\'\xc3\xbanica manera de poder utilitzar objectes de manera polim\xc3\xb2rfica sigui que comparteixin una arrel comuna, \xc3\xa9s a dir, una jerarquia de classes, ja que aix\xc3\xb2 proporciona la compatibilitat de tipus de dades necess\xc3\xa0ria perqu\xc3\xa8 sigui possible utilitzar una mateixa variable de refer\xc3\xa8ncia (que podr\xc3\xa0 apuntar a objectes de diverses subclasses d\'aquesta jerarquia) per enviar el mateix missatge (o un grup de missatges) al grup d\'objectes que es tracten de manera polim\xc3\xb2rfica._NEWLINE_No obstant aix\xc3\xb2, alguns llenguatges de programaci\xc3\xb3 (Java, C ++) permeten que dos objectes de diferents jerarquies de classes responguin als mateixos missatges, a trav\xc3\xa9s de les anomenades interf\xc3\xadcies (aquesta t\xc3\xa8cnica es coneix com a composici\xc3\xb3 d\'objectes). Dos objectes que implementin la mateixa interf\xc3\xadcie podran ser tractats de forma id\xc3\xa8ntica, com un mateix tipus d\'objecte._NEWLINE_En la programaci\xc3\xb3 orientada a objectes, l\'ess\xc3\xa8ncia del polimorfisme no afecta a la classe de la qual provenen els objectes. Tot i aix\xc3\xad, en els llenguatges basats en classes, \xc3\xa9s habitual (i en alguns potser \xc3\xa9s l\'\xc3\xbanica manera) que aquests objectes pertanyen a subclasses que pertanyen a una mateixa jerarquia. Llavors, el polimorfisme s\'ha de veure com una forma flexible d\'usar un grup d\'objectes (com si fossin nom\xc3\xa9s un). Es podria dir que el polimorfisme en ess\xc3\xa8ncia es refereix al comportament dels objectes, no a la seva pertinen\xc3\xa7a a una jerarquia de classes (o als seus tipus de dades)._NEWLINE_Un exemple. Podem crear dues classes diferents: Peix i Au que hereten de la superclasse  Animal. La classe Animal t\xc3\xa9 el m\xc3\xa8tode abstracte moure que s\'implementa de manera diferent en cadascuna de les subclasses (peixos i aus es mouen de manera diferent). Llavors, un tercer objecte pot enviar el missatge moure a un grup d\'objectes PeixAu per mitj\xc3\xa0 d\'una variable que faci refer\xc3\xa8ncia a la classe Animal, fent aix\xc3\xad un \xc3\xbas polim\xc3\xb2rfic d\'aquests objectes respecte al missatge moure._NEWLINE_El concepte de polimorfisme, des d\'una perspectiva m\xc3\xa9s general, es pot aplicar tant a funcions com a tipus de dades. Aix\xc3\xad neixen els conceptes de funcions polim\xc3\xb2rfiques i tipus polim\xc3\xb2rfics. Les primeres s\xc3\xb3n aquelles funcions que poden avaluar-se o ser aplicades a diferents tipus de dades de forma indistinta; els tipus polim\xc3\xb2rfics, per la seva banda, s\xc3\xb3n aquells tipus de dades que contenen almenys un element el qual el tipus no est\xc3\xa0 especificat.\n_START_SECTION_\nClassificaci\xc3\xb3\n_START_PARAGRAPH_\nEs pot classificar el polimorfisme en quatre grans tipus:\n_START_SECTION_\nPolimorfisme ad hoc\n_START_PARAGRAPH_\nEl polimorfisme ad hoc (o polimorfisme est\xc3\xa0tic) \xc3\xa9s aquell en qu\xc3\xa8 el codi necessita el tipus de dades amb les quals es treballa, \xc3\xa9s a dir, els tipus de dades han de ser expl\xc3\xadcits i declarats un per un abans de poder ser utilitzats.\n_START_SECTION_\nPolimorfisme param\xc3\xa8tric\n_START_PARAGRAPH_\nEl polimorfisme param\xc3\xa8tric (o polimorfisme din\xc3\xa0mic) \xc3\xa9s aquell en qu\xc3\xa8 el codi no inclou cap tipus d\'especificaci\xc3\xb3 sobre el tipus de dades sobre les quals treballa, per tant, pot ser utilitzada transparentment amb qualsevol nombre de nous tipus. La independ\xc3\xa8ncia envers les dades provoca que pot ser utilitzat per qualsevol tipus de dades compatible. En programaci\xc3\xb3 orientada a objectes, se\'n sol dir programaci\xc3\xb3 gen\xc3\xa8rica. En la comunitat de programaci\xc3\xb3, aquest \xc3\xa9s el polimorfisme m\xc3\xa9s habitual i se\'n sol dir simplement polimorfisme._NEWLINE_El polimorfisme din\xc3\xa0mic unit a l\'her\xc3\xa8ncia es coneix com a programaci\xc3\xb3 gen\xc3\xa8rica._NEWLINE_El concepte de polimorfisme param\xc3\xa8tric s\'aplica tant a tipus de dades com a funcions. Una funci\xc3\xb3 que pot ser avaluada o ser aplicada als valors dels diferents tipus es coneix com una funci\xc3\xb3 polim\xc3\xb2rfica. Un tipus de dades que poden semblar d\'un tipus generalitzat (per exemple, una llista amb els elements de tipus arbitrari) es designa tipus de dades polim\xc3\xb2rfic igual que el tipus generalitzat de qu\xc3\xa8 estan fetes aquestes especialitzacions. _NEWLINE_El seg\xc3\xbcent exemple mostra un tipus de dades llista parametritzada i dues funcions de forma param\xc3\xa8tricament polim\xc3\xb2rfiques entre elles:_NEWLINE_data List a = Nil | Cons a (List a)_NEWLINE_ _NEWLINE_length\xc2\xa0:: List a -> Integer_NEWLINE_length Nil         = 0_NEWLINE_length (Cons x xs) = 1 + length xs_NEWLINE_ _NEWLINE_map\xc2\xa0:: (a -> b) -> List a -> List b_NEWLINE_map f Nil         = Nil_NEWLINE_map f (Cons x xs) = Cons (f x) (map f xs)_NEWLINE_El polimorfisme param\xc3\xa8tric tamb\xc3\xa9 est\xc3\xa0 disponible en diversos llenguatges orientats a objectes, on sovint es coneix amb el nom de "gen\xc3\xa8rics" (per exemple, Java) o "plantilles" (C ++):_NEWLINE_class List<T> {_NEWLINE_  class Node<T> {_NEWLINE_        T elem;_NEWLINE_         Node<T> next;_NEWLINE_    }_NEWLINE_     Node<T> head;_NEWLINE_  int length() { ... }_NEWLINE_}_NEWLINE_ _NEWLINE_ List<B> map(Func<A,B> f, List<A> xs) {_NEWLINE_     ..._NEWLINE_ }\n_START_SECTION_\nSubtipatge\n_START_PARAGRAPH_\nAlguns llenguatges utilitzen la idea de subtipatge per a restringir la gamma de tipus que es poden utilitzar en un cas particular de polimorfisme. En aquests llenguatges, el polimorfisme de subtipus (de vegades conegut com a polimorfisme d\'inclusi\xc3\xb3 o polimorfisme din\xc3\xa0mic) permet una funci\xc3\xb3 per a ser escrit per prendre un objecte d\'un tipus determinat T, per\xc3\xb2 tamb\xc3\xa9 funcionar\xc3\xa0 correctament si s\'aprova un objecte que pertany a un tipus S que \xc3\xa9s un subtipus de T (d\'acord amb el principi de substituci\xc3\xb3 Liskov). Aquesta relaci\xc3\xb3 de tipus de vegades s\'escriu S <: T. Per contra, T es diu que \xc3\xa9s un Supertipus de S escrit T\xc2\xa0:> S. _NEWLINE_En el seg\xc3\xbcent exemple fem gats i gossos subtipus d\'animals. El procediment escoltem() accepta un animal, per\xc3\xb2 tamb\xc3\xa9 funcionar\xc3\xa0 correctament si es passa un subtipus:_NEWLINE_abstract class Animal {_NEWLINE_    abstract String parla();_NEWLINE_}_NEWLINE_ _NEWLINE_class Gat extends Animal {_NEWLINE_    String parla() {_NEWLINE_        return "Miau!";_NEWLINE_    }_NEWLINE_}_NEWLINE_ _NEWLINE_class Gos extends Animal {_NEWLINE_    String parla() {_NEWLINE_        return "Guau!";_NEWLINE_    }_NEWLINE_}_NEWLINE_ _NEWLINE_void escoltem(Animal a) {_NEWLINE_    println(a.parla());_NEWLINE_}_NEWLINE_ _NEWLINE_void main() {_NEWLINE_    escoltem(new Gat());_NEWLINE_    escoltem(new Gos());_NEWLINE_}_NEWLINE__NEWLINE_En un altre exemple, si els naturals, racionals, i enters s\xc3\xb3n tipus tals que Natural:> Racional i Natural:> Enter, una funci\xc3\xb3 escrita per tenir un nombre funcionar\xc3\xa0 igualment b\xc3\xa9 quan es passa un enter o racional com quan es passa d\'un natural. El tipus real de l\'objecte es pot amagar dels clients en una "capsa", i s\'accedeix a trav\xc3\xa9s de la identitat de l\'objecte. De fet, si el tipus de nombre \xc3\xa9s abstracta, \xc3\xa9s possible que ni tan sols sigui possible per aconseguir les seves mans en un objecte el tipus m\xc3\xa9s derivat sigui natural. Aquest tipus particular de jerarquia de tipus es coneix, especialment en el context del "Llenguatge de programaci\xc3\xb3 en Esquema", com una torre num\xc3\xa8rica, i en general cont\xc3\xa9 molts m\xc3\xa9s tipus. _NEWLINE_Llenguatges de programaci\xc3\xb3 orientats a objectes ofereixen subtipatge polim\xc3\xb2rfic utilitzant subclasses (tamb\xc3\xa9 conegut com a her\xc3\xa8ncia). En implementacions t\xc3\xadpiques, cada classe cont\xc3\xa9 el que s\'anomena una taula virtual, una taula de funcions que implementen la part polim\xc3\xb2rfica de la classe d\'interf\xc3\xadcie i cada objecte cont\xc3\xa9 un punter a la "vtable" de la seva classe, que \xc3\xa9s consultat a continuaci\xc3\xb3, cada vegada que s\'invoca un m\xc3\xa8tode polim\xc3\xb2rfic.\n_START_SECTION_\nDades gen\xc3\xa8riques\n_START_PARAGRAPH_\n....\n_START_SECTION_\nExemple de polimorfisme\n_START_PARAGRAPH_\nEn el seg\xc3\xbcent exemple fem \xc3\xbas del llenguatge C++ per il\xc2\xb7lustrar el polimorfisme. S\'observa a la vegada l\'\xc3\xbas de les funcions virtuals pures (funcions que constitueixen una interf\xc3\xadcie m\xc3\xa9s consistent quan es treballa amb una jerarquia de classes), ja que fan possibles l\'enlla\xc3\xa7 durant l\'execuci\xc3\xb3. No obstant aix\xc3\xb2, perqu\xc3\xa8 el polimorfisme funcioni, no \xc3\xa9s condici\xc3\xb3 necess\xc3\xa0ria que totes les funcions de la classe base estiguin declarades com virtual._NEWLINE_#include<iostream>using namespace std;class Figura {_NEWLINE_  private:_NEWLINE_  float base;_NEWLINE_  float altura; _NEWLINE_  public:_NEWLINE_ void captura();_NEWLINE_ virtual unsigned float perimetre()=0;_NEWLINE_ virtual unsigned float area()=0;};class Rectangle: public Figura { _NEWLINE_ public:_NEWLINE_  void imprimeix();_NEWLINE_  unsigned float perimetre(){return 2*(base+altura);}_NEWLINE_  unsigned float area(){return base*altura;}};class Triangle: public Figura {_NEWLINE_ public:_NEWLINE_  void mostra();_NEWLINE_  unsigned float perimetre(){return 2*altura+base}_NEWLINE_  unsigned float area(){return (base*altura)/2;}};void Figura::captura(){_NEWLINE_ cout << "CALC\xc3\x9aL DE L\'\xc3\x80REA I EL PERIMETRE D\'UN TRIANGLE IS\xc3\x92CELES I UN RECTANGLE:" << endl;_NEWLINE_ cout << "Escriu l\'altura: ";_NEWLINE_ cin >> altura;_NEWLINE_ cout << "Escriu la base: ";_NEWLINE_ cin >> base;_NEWLINE_ cout << "EL PERIMETRE \xc3\x89S: " << perimetre();_NEWLINE_ cout << "L\'\xc3\x80REA \xc3\x89S: " << area();getchar();return 0;}\n_START_SECTION_\nPolimorfisme des d\'una interf\xc3\xadcie\n_START_PARAGRAPH_\nTot i que el polimorfisme \xc3\xa9s el mateix s\'apliqui on s\'apliqui, la manera en qu\xc3\xa8 s\'aplica des d\'una interf\xc3\xadcie pot resultar una mica m\xc3\xa9s fosc i dif\xc3\xadcil d\'entendre. S\'exposa un senzill exemple (en VB-NET) comentat per entendre com funciona aplicat des d\'una interf\xc3\xadcie, primer s\'escriu el codi i despr\xc3\xa9s es comenta el funcionament._NEWLINE_Nota: per no enterbolir el codi en exc\xc3\xa9s, tot el que no es declara privat se sobreent\xc3\xa9n que \xc3\xa9s p\xc3\xbablic._NEWLINE_ \' Declarem una interf\xc3\xadcie anomenada IOperar i declarem la funci\xc3\xb3 Operar que implementaran les classes desitjades: _NEWLINE_ Interface IOperar_NEWLINE_ Function Operar(valor1 as integer, valor2 as integer) as long_NEWLINE_ End Interface_NEWLINE_ _NEWLINE_  \' Declarem una classe que treballa m\xc3\xa9s allunyada de l\'usuari i que contindr\xc3\xa0 funcions comunes per les seg\xc3\xbcents classes. _NEWLINE_  \' Si no fossin id\xc3\xa8ntiques haurien d\'anar a la interf\xc3\xadcie. _NEWLINE_  Class Operaci\xc3\xb3_NEWLINE_  Function Calcular(classecrida as Object) as Long _NEWLINE_  \' Aqu\xc3\xad s\'hauria de dir el codi com\xc3\xba a totes les operacions que criden a aquesta funci\xc3\xb3. _NEWLINE__NEWLINE_  \' Se suposa que la funci\xc3\xb3 inputValor recull un valor d\'algun lloc._NEWLINE_  valor1 as integer = inputValor() _NEWLINE_  valor2 as integer = inputValor()_NEWLINE_ _NEWLINE_  op as New IOperar = classecrida_NEWLINE_  Return op.Operar(valor1,valor2) \' Aqu\xc3\xad \xc3\xa9s on s\'utilitza el polimorfisme._NEWLINE_  End Function_NEWLINE_  End Class_NEWLINE_  \' Declarem 2 classes: Sumar i Restar que implementen la interf\xc3\xadcie i que criden a la classe Operaci\xc3\xb3:_NEWLINE_  Class Sumar_NEWLINE_  Implements IOperar_NEWLINE_  Private Function Operar(valor1 as Integer, valor2 as Integer) as Long Implements IOperar.Operar_NEWLINE_  Return valor1 + valor2_NEWLINE_  End Function_NEWLINE_ _NEWLINE_  Function Calcular() as Long_NEWLINE_  op as New operacion_NEWLINE_  Return op.Calcular(Me) \' es crida a la funci\xc3\xb3 \'Calcular\' de la classe \'Operaci\xc3\xb3\'_NEWLINE_  End Function_NEWLINE_  End Class_NEWLINE_  \' Segona classe._NEWLINE_  Class Restar_NEWLINE_  Implements IOperar_NEWLINE_  Private Function Operar(valor1 as Integer, valor2 as Integer) as Long Implements IOperar.Operar_NEWLINE_  Return valor1 - valor2_NEWLINE_  End Function_NEWLINE_ _NEWLINE_  Function Calcular() as Long_NEWLINE_  op as New operacion_NEWLINE_  Return op.Calcular(Me) \' es crida a la funci\xc3\xb3 \'Calcular\' de la classe \'Operaci\xc3\xb3\'_NEWLINE_  End Function_NEWLINE_  End Class_NEWLINE_Analitzem ara el codi per a entendre el polimorfisme exposat a la interf\xc3\xadcie: La interf\xc3\xadcie exposa un m\xc3\xa8tode que pot ser implementat per les diferents classes, normalment relacionades entre si. Les classes Sumar i Restar implementen la interf\xc3\xadcie per\xc3\xb2 el m\xc3\xa8tode de la interf\xc3\xadcie el declarem privat per evitar ser accedit lliurement ia m\xc3\xa9s tenen un m\xc3\xa8tode anomenat Calcularque crida a la classe Operaci\xc3\xb3on tenim un altre m\xc3\xa8tode amb el mateix nom. \xc3\x89s aquesta classe \xc3\xbaltima la que realitza el polimorfisme i ha de fixar-se com \xc3\xa9s a trav\xc3\xa9s d\'una inst\xc3\xa0ncia de la interf\xc3\xadcie que crida al m\xc3\xa8tode operar. La interf\xc3\xadcie sap a quin m\xc3\xa8tode de quina classe trucar des del moment que assignem un valor a la variable OP al m\xc3\xa8tode Calcular de la classe Operaci\xc3\xb3, que al seu torn va rebre la refer\xc3\xa8ncia del m\xc3\xa8tode Calcular des de la classe que la flama, sigui quina sigui, s\'identifica a si mateixa, mitjan\xc3\xa7ant la refer\xc3\xa8ncia This segons el llenguatge emprat. Cal notar que la inst\xc3\xa0ncia de la interf\xc3\xadcie accedeix als seus m\xc3\xa8todes encara que en les seves classes s\'hagin declarat privades.\n_START_SECTION_\nPolimorfisme de sobre-c\xc3\xa0rrega i de sobre-escriptura\n_START_PARAGRAPH_\nEl polimorfisme de sobre-c\xc3\xa0rrega, consisteix a implementar diverses vegades un mateix m\xc3\xa8tode per\xc3\xb2 amb par\xc3\xa0metres diferents, de tal manera que en invocar-lo, el compilador decideix quin dels m\xc3\xa8todes s\'ha d\'executar, en funci\xc3\xb3 dels par\xc3\xa0metres de la crida._NEWLINE_Tamb\xc3\xa9 s\'anomena polimorfisme de sobrec\xc3\xa0rrega si una funci\xc3\xb3 actua sobre el mateix tipus de variables. Aquest polimorfisme el suporten la gran major\xc3\xada de llenguatges._NEWLINE_(Per exemple: es pot fer "i + j" amb "ints" o "floats")_NEWLINE_Un altre exemple:_NEWLINE_int entraElTeuPes (int pes) { .... codi1 .... }_NEWLINE_int entraElTeuPes (String pes) { .... codi2 .... }_NEWLINE__NEWLINE_void funcio () {_NEWLINE_entraElTeuPes (65); // Invoca el primer m\xc3\xa8tode executant el "codi1"._NEWLINE_entraElTeuPes ("65"); // Invoca el segon m\xc3\xa8tode executant el "codi2"._NEWLINE_}_NEWLINE_El polimorfisme de sobre-escriptura, consisteix en reimplementar un m\xc3\xa8tode heretat d\'una superclasse amb exactament la mateixa definici\xc3\xb3 (incloent nom de m\xc3\xa8tode, par\xc3\xa0metres i valor de retorn). Aix\xc3\xb2 permet que en funci\xc3\xb3 de la classe de pertinen\xc3\xa7a d\'un objecte, el compilador determini quin dels m\xc3\xa8todes ha d\'executar. (Recorda que la classe de pertinen\xc3\xa7a correspon a la classe de la qual s\'ha invocat el m\xc3\xa8tode constructor mitjan\xc3\xa7ant la sent\xc3\xa8ncia "new")._NEWLINE_class Clase1 {_NEWLINE_metode1 () { ... codi 1 ... } }_NEWLINE_class Clase2 extends Clase1 () {_NEWLINE_metode1 () { ... codi 2 ... } }_NEWLINE_Clase1 objecte1 = new Clase1 ();_NEWLINE_objecte1.metode1 (); // Invoca el primer m\xc3\xa8tode executant el "codi 1"._NEWLINE_Clase1 objecte2 = new Clase2 ();_NEWLINE_objecte2.metode1 (); // Invoca el segon m\xc3\xa8tode executant el "codi 2".'