Polimorfisme (programació): diferència entre les revisions

Contingut suprimit Contingut afegit
Cap resum de modificació
nivells d'encapçalament; faltes
Línia 5:
Hi ha dos tipus genèrics de polimorfisme: el polimorfisme de sobre-càrrega (''[[overload]]'') i el polimorfisme de sobre-escriptura (''[[override]]'').
 
=== Descripció ===
En el llenguatge basat en classes i amb un sistema de tipus de dades fort (independententindependentment de si la verificació es realitza en temps de compilació o d'execució), és possible que l'única manera de poder utilitzar objectes de manera polimòrfica sigui que comparteixin una arrel comuna, és a dir, una jerarquia de classes, ja que això proporciona la compatibilitat de tipus de dades necessària perquè sigui possible utilitzar una mateixa variable de referència (que podrà 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òrfica.
 
No obstant això, alguns llenguatges de programació (Java, C ++) permeten que dos objectes de diferents jerarquies de classes responguin als mateixos missatges, a través de les anomenades interfícies (aquesta tècnica es coneix com a composició d'objectes). Dos objectes que implementin la mateixa interfície podran ser tractats de forma idèntica, com un mateix tipus d'objecte,alguns llenguatges de programació (Java, C ++) permeten que dos objectes de diferents jerarquies de classes responguin als mateixos missatges, a través de les anomenades interfícies (aquesta tècnica es coneix com a composició d'objectes). Dos objectes que implementin la mateixa interfície podran ser tractats de forma idèntica, com un mateix tipus d'objecte el tipus definit per la interfície.
Línia 12:
En la programació orientada a objectes, l'essència del polimorfisme no afecta a la classe de la qual provenen els objectes. Tot i així, en els llenguatges basats en classes, és habitual (i en alguns potser és l'única 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és un). Es podria dir que el polimorfisme en essència es refereix al comportament dels objectes, no a la seva pertinença a una jerarquia de classes (o als seus tipus de dades).
 
Un exemple. Podem crear dues classes diferents: Peix i Au que hereten de la superclasesuperclasse Animal. La classe Animal té el mètode 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à d'una variable que fagifaci referència a la classe Animal, fent així un ús polimòrfic d'aquests objectes respecte al missatge moure.
 
El concepte de polimorfisme, des d'una perspectiva més general, es pot aplicar tant a funcions com a tipus de dades. Així neixen els conceptes de funcions polimòrfiques i tipus polimòrfics. Les primeres són aquelles funcions que poden avaluar-se o ser aplicades a diferents tipus de dades de forma indistinta; els tipus polimòrfics, per la seva banda, són aquells tipus de dades que contenen almenys un element el qual el tipus no està especificat.
=== Classificació ===
Es pot classificar el polimorfisme en quatre grans tipus:
 
==== PoliformismePolimorfisme ad hoc ====
El [[Polimorfisme ad hoc|poliformismepolimorfisme ad hoc]] (o poliformismepolimorfisme estàtic) és aquell en què el codi necessita el tipus de dades amb les quals es treballa, és a dir, els tipus de dades han de ser explicitsexplícits i declarats un per un abans de poder ser utilitzats.
==== PoliformismePolimorfisme paramètric ====
El poliformismepolimorfisme paramètric (o poliformismepolimorfisme dinàmic) és aquell en què el codi no inclou cap tipus d'especificació sobre el tipus de dades sobre les quals treballa, per tant, pot ser utilitzada transparentment amb qualsevol nombre de nous tipus. La independència envers les dades provoca que pot ser utilitzat per qualsevol tipus de dades compatible. En programació orientada a objectes, se'n sol dir programació genèrica. En la communitatcomunitat de programació, aquest és el polimorfisme més habitual i se'n sol dir simplement polimorfisme.
 
El poliformismepolimorfisme dinàmic unit a la herència es coneix com [[programació genèrica]].
 
El concepte de polimorfisme paramètric s'aplica a tots dos tipus de dades i funcions. Una funció que pot avaluar o ser aplicada als valors dels diferents tipus es coneix com una funció polimòrfica. Un tipus de dades que poden semblar ser d'un tipus generalitzat (per exemple, una llista amb els elements de tipus arbitrari) es designa com ''tipus de dades polimòrfic'' com el tipus generalitzat de què estan fetes aquestes especialitzacions.
Línia 50:
}</nowiki>
 
==== Subtipatge ====
Alguns 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 polimorfisme d'inclusió o polimorfisme dinàmic) permet una funció per a ser escrit per prendre un objecte d'un tipus determinat T, però també funcionarà correctament si s'aprova un objecte que pertany a un tipus S que és un subtipus de T (d'acord amb el principi de substitució Liskov). Aquesta relació de tipus de vegades s'escriu S <: T. Per contra, T es diu que és un Supertipus de S escrit T :> S.
 
Línia 84:
Llenguatges de programació orientats a objectes ofereixen subtipatge polimòrfic utilitzant subclasses (també conegut com a herència). En implementacions típiques, cada classe conté el que s'anomena una taula virtual, una taula de funcions que implementen la part polimòrfica de la classe d'interfície i cada objecte conté un punter a la "vtable" de la seva classe, que és consultat a continuació, cada vegada que s'invoca un mètode polimòrfic.
 
==== Dades genèriques ====
....
 
=== Exemple de poliformismepolimorfisme ===
En el següent exemple fem ús del llenguatge C++ per il·lustrar el polimorfisme. S'observa a la vegada l'ús de les funcions virtuals pures (funcions que constitueixen una interfaceinterfície més consistent quan es treballa amb una jerarquia de classes) ja que fan possibles l'enllaç durant l'execució. No obstant això, perquè el polimorfisme funcioni, no és condició necessària que totes les funcions de la classe base estiguin declarades com virtual.
 
<source lang="c">
Línia 132:
</source>
 
=== Polimorfisme des d'una interfaceinterfície ===
Tot i que el polimorfisme és el mateix s'apliqui on s'apliqui, la manera en què s'aplica des d'una interfície pot resultar una mica més fosc i difícil d'entendre. S'exposa un senzill exemple (en VB-NET) comentat per entendre com funciona aplicat des d'una interfície, primer s'escriu el codi i després es comenta el funcionament.
 
Línia 138:
 
<source lang=vbnet>
' Declarem una interfaceinterfície anomenada IOperar yi declarem la funció Operar que implementaran les classes desitjades:
Interface IOperar
Function Operar(valor1 as integer, valor2 as integer) as long
Línia 146:
<source lang=vbnet>
' Declarem una classe que treballa més allunyada de l'usuari i que contindrà funcions comunes per les següents classes.
' Si no fossin identiquesidèntiques haurien d'anar a la interficieinterfície.
Class Operació
Function Calcular(classecrida as Object) as Long
Línia 156:
op as New IOperar = classecrida
Return op.Operar(valor1,valor2) ' AquiAquí és on s'utilitza el polimorfisme.
End Function
End Class
Línia 162:
 
<source lang=vbnet>
' Declarem 2 classes: Sumar yi Restar que implementen la interfaceinterfície i que criden a la classe Operació:
Class Sumar
Implements IOperar
Línia 193:
Analitzem ara el codi per a entendre el '''polimorfisme''' exposat a la interfície: La interfície exposa un mètode que pot ser implementat per les diferents classes, normalment relacionades entre si. Les classes ''Sumar'' i ''Restar'' implementen la interfície però el mètode de la interfície el declarem privat per evitar ser accedit lliurement ia més tenen un mètode anomenat ''Calcular''que crida a la classe ''Operació''on tenim un altre mètode amb el mateix nom. És aquesta classe última la que realitza el polimorfisme i ha de fixar-se com és a través d'una instància de la interfície que crida al mètode operar. La interfície sap a quin mètode de quina classe trucar des del moment que assignem un valor a la variable ''OP'' al mètode ''Calcular'' de la classe ''Operació'', que al seu torn va rebre la referència del mètode ''Calcular'' des de la classe que la flama, sigui quina sigui, s'identifica a si mateixa, mitjançant la referència ''This'' segons el llenguatge emprat. Cal notar que la instància de la interfície accedeix als seus mètodes tot i que en les seves classes s'hagin declarat privades.
 
=== Polimorfisme de sobre-càrrega i de sobre-escriptura ===
El polimorfisme de sobre-càrrega, consisteix a implementar diverses vegades un mateix mètode però amb paràmetres diferents, de tal manera que en invocar-lo, el compilador decideix quin dels mètodes s'ha d'executar, en funció dels paràmetres de la crida.
 
Línia 206:
void funcio () {
entraElTeuPes (65); // InvoncaInvoca el primer mètode executant el "codi1".
entraElTeuPes ("65"); // InvoncaInvoca el segon mètode executant el "codi2".
}