You are on page 1of 36

Paradigma

OrientadoaObjetos




Mdulo3:Polimorfismo.
Manejobsicodecolecciones.












porFernandoDodino
Versin2.0
Marzo2016


DistribuidobajolicenciaCreative Commons Share-a-like

Mdulo3:Polimorfismo.Manejobsicodecolecciones.

Indice

1IntroduccinalPolimorfismo
1.1Analoga
1.2Repasomensajeymtodo
1.3Breveejemplo
2Introduccinacolecciones
2.1Quesunacoleccin?
2.2Representacin
2.3Interfazdeunacoleccin
2.4IntroatiposdecoleccionesenWollok
3Ejemplointegrador:Misionesdeunhroe
3.1Shrek,nuestronicohroeenestelo
3.2Primeramisin:liberaraFiona
3.3Cuntasmisionestieneunhroe
3.4Segundamisin:buscarlapiedrafilosofal
3.5Filtrarmisionesdifciles
3.6Filtrarelementosdeunacoleccin
3.7Filteryelefectocolateral
3.8Map:Encargadosdeunamisin
3.9Facilitandolaspruebas
3.9.1ProgramaWollok
3.9.2Definiendovaloresdefaultparalosobjetos
3.10Fold:Sumarpuntosderecompensa
4Resumen

2de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

1IntroduccinalPolimorfismo
Qupasasidosobjetossoncapacesderesponderaunmismomensaje?
Elquemandaelmensajepuedecambiarlareferenciadeunobjetoaotrosinnotarla
diferencia.

Seproduceentoncesunconceptofundamentalenelparadigma,cuandotenemos3
objetos
unobjetoqueenvaunmensaje
ydosobjetosqueimplementanelmensajededosmanerasdiferentes(cada
unodefineunmtododistinto)

Elobservadorpuedecambiarlareferenciasinpreocuparseporelenvodelmensaje,
quepermanecesincambios.Decimosentoncesquelosdosobjetosquecomparten
ciertainterfazencomnsonpolimrficos.


Ojo, no es necesario que los dos objetos polimrficos definan exactamente los
mismos mtodos. Alcanza con que implementen al menos un mensaje en comn
(comoenelejemploelmtodohazTuGracia).

1.1Analoga
Para ilustrar este concepto utilizaremos algunas analogas, veamos el
botnPlayencadaunodeestosartefactos...

3de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

4de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

Todos los artefactos tienen la misma interfaz. Es decir que si lo llevramos a una
representacinenobjetos,podramosenviarlesatodoselmismomensaje:

Wollok interactive console (type "quit" to quit):


>>> ipod.play()
>>> dvdMio.play()
>>> vhsRecorder.play()

No obstante, est claro que cada artefacto hace cosas diferentes, porque sus
implementaciones son diferentes (los mtodos no son iguales). Ciertamente, no
podemospretenderquefuncionenigual,ynoloharn:unvideoreproductornopuede
grabar, de la misma manera que no podemos ir a la pista 8 de un cassette. Pero s
es til que varios objetos compartan lainterfaz,paraalguienqueuseaesosobjetos
dentrodealgncontexto.

Para quin es bueno eso? No para los objetos que son polimrficos, sino para
quienesusamosesosartefactos.

1.2Repasomensajeymtodo
Porqunoquierovercmoseimplementaelmtodoencadaobjeto?


Ah,cierto.Lacomplejidad.

5de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

1.3Breveejemplo
Tenemos dos empleados de un negocio que vende empanadas, Gimnez y
Baigorria. Gimnez cobra un sueldo fijo (hoy es 15.000, pero eso puede
modificarse). Baigorria cobra 15 pesos por cada empanada que vende. Generamos
elejemploenWollok:

object gimenez {
var sueldo = 15000

method sueldo() = sueldo

method sueldo(_sueldo) { sueldo = _sueldo }


}

object baigorria {
var cantidadEmpanadasVendidas = 100
var montoPorEmpanada = 15

method venderEmpanada() { cantidadEmpanadasVendidas += 1 }

method sueldo() = cantidadEmpanadasVendidas * montoPorEmpanada


}

LoprobamosenunREPL:
>>> baigorria.sueldo()
1500
>>> baigorria.venderEmpanada()
>>> baigorria.sueldo()
1515
>>> gimenez.sueldo()
15000

Vemos que tanto a baigorria como a gimenez podemos preguntarle el sueldo, no


nos importa cmo lo resuelve cada uno, s que en algn punto compartenlamisma
interfaz: mensaje sueldo() sin parmetros, a baigorria no le podemos asignar el
sueldo

>>> baigorria.sueldo(29)
ERROR: Method does not exist in well-known object (line: 1)

6de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

2Introduccinacolecciones

2.1Quesunacoleccin?
Lacoleccinnospermiterepresentarunconjuntodeobjetosrelacionados:
losjugadoresdeunequipodeftbol,uncardumendepeces,lascosasqueun
hroeguardaensumochila,unejrcito,sonejemplosdeestetipodeabstracciones.

Otradefinicinposibleesqueunacoleccinnossirveparamodelarunarelacin1a
N:
Unafacturatienemuchaslneasconproductos
Unescritorpublicvarioslibros
Unafiestatienemuchosinvitados
Unhroetienequecumplirvariasmisiones

Aprimeravistaunacoleccinesunconjuntodeobjetos.Silavemosconms
precisinnosdamoscuentaqueesmsprecisopensarlacomounconjuntode
referencias:loselementosnoestndentrodelacoleccin,sinoquelacoleccinlos
conoce.


Figura3.1:Lacoleccinesunconjuntodereferenciasaotrosobjetos

2.2Representacin
Podemosgraficarlarelacindinmicaentreunequipodeftbolylosjugadoresque
lointegranmedianteundiagramadeobjetos.Esteesundiagramacon
caractersticasdinmicas,porquemuestraelestadodelosobjetosenunmomento
determinado.

7de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.


Figura3.2:Elplanteldejugadoresdeunequipocomounacoleccindeobjetos

2.3Interfazdeunacoleccin
Supongamos que tenemos un lbum de fotos, otra representacin posible de una
coleccindeobjetos.Qupodemoshacerconesasfotografas?
Mirarlas,recorrerlas:iterarunacoleccin
Averiguarcuntasfotoshay:sabereltamaodeunacoleccin
Saber si est una determinada foto en el lbum, es decir, si un elemento
pertenecealacoleccin
Pegarunafotonueva:agregarunelementoalacoleccin
Regalarunafotoaalguien:eliminarunelementodelacoleccin
Seleccionar las fotos del viaje de 1999 a Ushuaia: filtrar elementos de una
coleccin
Saberlasfechasenlaquesaqumisfotos:transformarloselementosdeuna
coleccin
Saber si hay alguna foto de Navidad: determinar si alguno o todos los
elementossatisfacenuncriterio

2.4IntroatiposdecoleccionesenWollok
Aprimeravista,podemosdiferenciardosdiferentestiposdecoleccionesenWollok

losconjuntos,quemodelanalconjuntomatemtico:
nohayordenenloselementosynopuedehaber
elementosrepetidos.Sedefinenmedianteelliteral#{}
var numeros = #{1, 2, 3, 4}

8de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.


laslistas,endondeloselementostienenun
ordenypuedehaberelementosrepetidos.Se
definenmedianteelliteral[]
var fila = [francisco, mirta, hector]



3Ejemplointegrador:Misionesdeunhroe
Enunsistemaqueadministradiferentestiposdehroe,aunhroeselepuede
asignarmisionesynuevosobjetivos.Porejemplo,unmagopuedeencargarlebuscar
untemmgicoenunamontaalejana.Unancianopuedeencargarleliberarasu
hijadelosterriblestrollsquehabitanenlagrutadelossinnariz.

Cadavezqueunhroetieneunodeestosencuentros,anotalosdatosdelamisin
ensudiariopersonal.Todamisinsumaenelcaminodelhroe:lasmisionestienen
unarecompensaderespeto,queluegopuedecanjearsepororo.

Quabstraccionessurgen?Elhroetieneunacoleccindemisiones.Enprincipio
vamosapensarendostiposdemisiones:
1. buscaruntemmgico
2. liberaraunadoncella.

Ademsnosavisanqueexistenmisionesdifciles,quesonaquellasdonde
lamontaadondeesteltemabuscarquedaamsde100kms.obien
ladoncellaaliberarestcustodiadapor45trolls(nomsnimenos)

3.1Shrek,nuestronicohroeenestelo
Definiremosunobjetoshrek,ungran(anti)hroe.Porelmomentosabemosque
tienemisiones,laprimerapreguntaquenostenemosquehaceres:necesitamos
mantenerelordendecadaunadelasmisiones?podemosasignarledosvecesla
mismamisin?Aprimeravista,elordennopareceimportanteyvamosasuponer

9de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

que,delamismamaneraqueunonopuedebaarsedosvecesenelmismoro1,uno
noliberaalamismadoncelladosveces.

object shrek {
var misiones = #{}
}

Fig.3.3:Misionesesunareferenciaaunconjunto

3.2Primeramisin:liberaraFiona
ShrektienesuprimeramisinasignadaporLordFarquaad:liberaraunadoncella
encerradaenlatorremsaltadeuncastilloprotegidoporunejrcitode5trolls2.
CreamosunobjetoquerepresentalamisindeliberaraFiona

object liberarAFiona {

Ellectorobservarquenodefinimostodavacomportamientonimuchomenos
atributos,porelmomentonuestroobjetivoesincorporarlamisinalhroeyno
queremosadelantarnosnitomardecisionesantesdetiempo.

Pensamoscmoagregarlamisinalhroe:necesitamosmandarleunmensajea
shrek:
>>> shrek.agregarMision(liberarAFiona)

Entoncesenshrek,debemosescribirelmtodoagregarMision(),quedelegala
accinalobjetoqueestrepresentandolacoleccin:

object shrek {
var misiones = #{}
method agregarMision(_mision) { misiones.add(_mision) }
1
EnrealidadeldichodeHerclitoes
, .
Enlosmismosrosentramosynoentramos,[pues]somosynosomos[losmismos].
Estoimplicaquetantoelrocomoelquesebaaenlcambiantodoeltiempo.

2
Luegodeunosaos,laDragonadeciditercerizarlaseguridad.
10de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

Cuandoenviemoselmensajeashrek
>>> shrek.agregarMision(liberarAFiona)

ennuestroambientetendremosestasreferencias:


Fig3.4:Primeramisinparashrek

3.3Cuntasmisionestieneunhroe
Cmosabemoscuntasmisionestieneunhroe?Lepreguntamosashrek
shrek.cantidadDeMisiones()

Sondosmomentosdiferenciados:
1) primerolainterfaz,
2) luegocmoimplementarlo

object shrek {
...
method cantidadDeMisiones() = misiones.size()3
}

3.4Segundamisin:buscarlapiedrafilosofal
Shreksecruzainesperadamenteconeldirectordeunafamosaescuelademagia,
quienlepidequeensecretobusqueunafamosapiedrafilosofalquedejolvidado
unanochedeborracheraenlosmontesUrales,a40kms.delpantanodondevive
nuestrohroe.

CreamosentoncesnuestroobjetobuscarPiedraFilosofal:

3
Aquestamosusandounasintaxisnueva,queequivaleahacer
method cantidadDeMisiones() { return misiones.size() }
Wollokpermiteestadefinicinsimplificadadelmtodocuandoabarcaunasolalneaydevuelveun
valor.Encasodedudarecomendamosseguirconlasintaxisoriginal.
11de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

object buscarPiedraFilosofal { }

Ycorremosnuevamentelaconsolainteractiva,agregandoambasmisiones:
>>> shrek.agregarMision(liberarAFiona)
>>> shrek.agregarMision(buscarPiedraFilosofal)

Podemosvolverapreguntarashreklacantidaddemisiones,noesperamos
sorprenderallectorconlarespuesta.

3.5Filtrarmisionesdifciles
Nuestronuevorequerimientonecesitaaplicarvariosconceptos,vamosconel
primero:lasmisionesliberaraFionaybuscarlapiedrafilosofaltienenque
entenderelmismomensaje.

>>> liberarAFiona.esDificil()
>>> buscarPiedraFilosofal.esDificil()

Entonces,necesitamosqueseanpolimrficos.Paraquinesesto?Noparalas
misiones,sinoparashrek,queesquienposteriormentelosvaausar.Perononos
apuremos,ahorastenemosquedefinirelcomportamientoenlasmisiones

object liberarAFiona {
var cantidadTrolls = 5
method esDificil() = cantidadTrolls.between(4, 5)
}

object buscarPiedraFilosofal {
var kilometrosDistancia = 40
method esDificil() = kilometrosDistancia > 100
}

Fjensequenonecesitamos-porelmomento-definiraccessorsparalosatributosde
losobjetosliberarAFionaybuscarPiedraFilosofal.

3.6Filtrarelementosdeunacoleccin
CmopreguntoqumisionesdifcilestieneShrek?
>>> shrek.misionesDificiles()
#liberarAFiona[cantidadTrolls=5, solicitante=Lord Farquaad]

Lascoleccionesdefinenunmensajefilter,alquelepodemospasarelcriterioque
debencumplirloselementosquenosinteresan:

object shrek {
12de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

...
method misionesDificiles() =
misiones.filter({ mision => mision.esDificil() })

Msadelanteveremosenprofundidadelobjetoqueleestamospasandocomo
parmetroafilter,porahoranosalcanzaconverlasimilitudquetieneestasolucin
conlaformadetrabajoenelparadigmafuncional.

Pararesolverlasmisionesdifciles
shrekconoceasusmisiones
perodelegalarespuestaacadamisin,queentiendeelmensaje
esDificil().Noimportacmoloimplementan,loimportanteesquetodos
devuelvenunvalorbooleanoquepermitediscriminarmisionesfcilesde
difciles.

3.7Filteryelefectocolateral
ElresultadodeenviarelmensajemisionesDifciles()noalteralasreferenciasdela
coleccinoriginal:


Figura3.5:Filterdevuelveunacopiadelacoleccin
conloselementosquecumplenunacondicin

Estopermitehacerconsultassinquehayaefectosobrelasreferenciasoriginales,no
seralgicoquealquererconocerlosclientesquenosdebenplataperdamoslos
quespagaron4.

4
DelamismamanerafuncionaelfilterquehemosvistoenHaskell,facilitadoporlaausenciade
asignacionesdestructivas
13de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

3.8Map:Encargadosdeunamisin
Cadamisintieneunsolicitante,representadoporunString.Loincorporamosen
nuestrasdefiniciones:
object liberarAFiona {
...
var solicitante = ""
method solicitante() = solicitante
method solicitante(_solicitante) { solicitante = _solicitante }
}

object buscarPiedraFilosofal {
...
var solicitante = ""
method solicitante() = solicitante
method solicitante(_solicitante) { solicitante = _solicitante }
}

Ellectorsepreguntar,noserepiteelcdigo?S,porahorasomostolerantes
respectoaesto.

Cmolepedimosashreklossolicitantesdetodassusmisiones?
>>> liberarAFiona.solicitante("Lord Farquaad")
>>> buscarPiedraFilosofal.solicitante("Mr Dumblecofcofdore")
>>> shrek.agregarMision(liberarAFiona)
>>> shrek.agregarMision(buscarPiedraFilosofal)
>>> shrek.solicitantesDeMisMisiones()
#{"Lord Farquaad", "Mr Dumblecofcofdore"}

AhorapodemospensarenelmtodosolicitantesDeMisMisiones()quetieneque
aplicarunatransformacinacadaelementodelacoleccin:

INPUT:unamisin OUTPUT:susolicitante(unString)

cmolologramos:mision.solicitante()

Nosayudamosconelmensajemap()alacoleccin:
object shrek {
...
method solicitantesDeMisMisiones() =
misiones.map({ mision => mision.solicitante() })
}

Aligualquefilter,mapnotieneefectocolateral:

14de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.


Figura3.5:Mapdevuelveunacoleccinnuevaconloselementostransformados

Estotienesentido,porqueademspasamosdeunconjuntodemisionesaun
conjuntodesolicitantes.

3.9Facilitandolaspruebas
Cadavezquesemodificaelcomportamientodeunobjeto,esuntantotedioso
volverarecuperarelestadoquenecesitotenerparapoderhacermispruebas.
Dejamosaqudosalternativasmientrasaguardamosalcaptuloespecialdedicadoa
laspruebasunitarias:

3.9.1ProgramaWollok
EscribirunprogramaWollokdonderepitamoslasecuenciademensajesesperado.
Estotienelaventajadeenviartodoslosmensajesjuntos,aunque
notendremosunentornointeractivodeprueba,elprogramaseejecutayse
termina(losobjetosnoestarnmsenelambiente)
necesitamosserexplcitosenloquequeremosverporconsola(enviando
console.println)
yademstenemosqueimportarlosobjetosquecreamosenelarchivode
wollok(enlaprimeralneaharemosimportheroes.*paraquepodamos
referenciaratodoslosobjetosdefinidosenelarchivoheroes.wlk):

import heroes.*

program heroes {
liberarAFiona.cantidadTrolls(5)5

5
Agregamosparaesolosaccessors,comopodrnverenelejemplosubidoalrepositorio
https://github.com/wollok
15de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

liberarAFiona.solicitante("Lord Farquaad")
buscarPiedraFilosofal.kilometrosDistancia(40)
buscarPiedraFilosofal.solicitante("Mr Dumblecofcofdore")
shrek.agregarMision(liberarAFiona)
shrek.agregarMision(buscarPiedraFilosofal)
console.println(shrek.solicitantesDeMisMisiones())
}

Estoproduceelsiguienteoutput:
#{Mr Dumblecofcofdore, Lord Farquaad}

3.9.2Definiendovaloresdefaultparalosobjetos
Laestrategiaconsisteennodefinirvaloressininicializarparalosobjetos,sinolas
referenciasquenecesitamos.

object shrek {
var misiones = #{liberarAFiona, buscarPiedraFilosofal }

...

object liberarAFiona {
var cantidadTrolls = 4
var solicitante = "Lord Farquaad"

...

object buscarPiedraFilosofal {
var kilometrosDistancia = 40
var solicitante = "Mr DumblecofcofDore"

Deestamanera,aliniciarnuestroREPLpodemosdirectamentehacerlaspruebas
sobreshrek,liberarAFionaybuscarPiedraFilosofal:

>>> shrek.misionesDificiles()
#{liberarAFiona[cantidadTrolls=4, solicitante=Lord Farquaad]}

3.10Fold:Sumarpuntosderecompensa
Cadamisintieneunacantidaddepuntosderecompensa,unvalornumrico.Los
puntosderecompensaporliberaraunadoncellason2*cantidaddetrollsquela
custodian.Respectoabuscaruntemmgico,son10puntossiladistanciaa
recorreresmsde50kilmetros5encasocontrario.

object liberarAFiona {
...

16de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

method puntosRecompensa() = cantidadTrolls * 2


}

object buscarPiedraFilosofal {
...
method puntosRecompensa() {
if (kilometrosDistancia > 50) {
return 10
} else {
return 5
}
}
}

Nuevamente,podemosenviarmensajesaliberarAFionaobuscarPiedraFilosofalen
formaindistinta!Encontramosotrocontextoenelcualambosobjetosson
polimrficos.Yestonospermiteresolvernuestrotercerrequerimiento:queremos
saberlospuntosderecompensadelasmisionesquetieneencargadounhroe,esto
selogra...enviandoelsiguientemensaje
>>> shrek.totalPuntosDeRecompensa()
15

claroest.

Loresolvemosaprovechandootraconstruccinconocidapornosotros:fold,que
necesitaelcriterioparareducirloselementosqueformanpartedelacoleccinaun
valorfinal.Elvalorinicialdelacumulador,es0.

object shrek {
...
method totalPuntosDeRecompensa() =
misiones.fold(0, { acum, mision =>
acum + mision.puntosRecompensa() })
}

Yaquvemosclaramentequeshrekaprovechaelpolimorfismoparasumarlos
puntosderecompensadelasmisiones,sinimportarlecmolotermina
implementandocadauna.

4Resumen
Eneste(extenso)captuloconocimosunodelosconceptosfundamentalesdel
paradigma:elpolimorfismocomounaherramientaparaagruparobjetosquetienen

17de18
Mdulo3:Polimorfismo.Manejobsicodecolecciones.

diferentecomportamiento(distintocdigo)perolamismainterfaz.Entoncespuedo
enviarlesmensajessinsabercmoloimplementan,einclusosinsaberaquobjeto
particularleestoyhablando:puedocambiarlareferenciasintenerquehacer
cambios.Porltimohemosconocidolascoleccionescomounaformadeteneruna
referenciaamltiplesobjetos,ycomenzamosaconocersuricainterfazquenos
permiteresolverrequerimientossinnecesidaddetenerquebajardemasiadoa
detalleelalgoritmo.

18de18

You might also like