Sie sind auf Seite 1von 16

Introduccinalaprogramacinorientadaaobjetos conPython

Notasacercadeesteartculo
Esteartculohasidoextradodelapginawebhttp://blog.rvburke.comcumpliendoconlanormadecopyright establecida.

CopyrightRafaelVillarBurke,2006.Sepermiteladistribucin,copiaymodificacindelostextos, siempreycuandoseindiquenloscambiosrealizados,seconserveelcopyrightyestanota.

SuautororiginalesRafaelVillarBurkeyelartculodatadel22deNoviembrede2006.LaversinenPDFhasido realizadaporOscarCarballalPregoydatadel24deNoviembrede2009.

Sehaprocedidoahaceralgunasconcesionesvisualesdecaraaorientarallectordeformamsintuitivaaloque estviendoencadamomento.Lostextoscontenidosencajasgrisesserefierenalneasdecdigo,ylostextos contenidosencajasconbordenegrosonlasrepresentacionesdelosdatosquedeberansalirporpantalla.Esto sejuntaconlasconcesionesyaestablecidasenelartculooriginal,lascualessonmostradasmsabajo.

Icode,thereforeIam.

Esteartculoesunaintroduccinalaprogramacinorientadaaobjetos(POO,oOOPporsussiglaseningls), unodelosparadigmasdeprogramacinestructuradamsimportantehoyenda. ElartculousaellenguajePythonparalosdistintosejemplos,yexplicalaimplementacindelaPOOenese lenguaje,aunqueabordaconceptosgeneralesquesonfcilmentetrasladablesaotroslenguajes. Losfragmentosdecdigosesealanusandounestilodetextodiferente(anchofijo)y,cuandoseutilizael intrpretedepython,seprefijacadalneaconlossmbolos>>>.Estaintroduccinpresuponeconocimientos bsicosdeprogramacinydellenguajepython.

Formasdepensar:paradigmasdeprogramacin
Unodeloselementosbsicosalahoraderealizarunprogramaeslamodelizacindelproblemaquepretende resolver.Esprecisolocalizarlasvariablesylosaspectosrelevantes,ascomocomprenderlospasosnecesarios paraobtenerelresultadoapartirdelosdatosiniciales,etc.Esdecir,abstraerelproblema,reduciendosus detallesdeformaquepodamostrabajarconpocoselementoscadavez. Laalgoritmiaplantealaformaptimaderesolverproblemasconcretos,talescomolaordenacindeunalistade elementos,labsquedadeunelementoenunconjunto,lamanipulacindeconjuntosdedatos,etc.Sin embargo,noproporcionanunmarcogeneral,unenfoque,quenospermitaplantearyformularlassolucionesa unproblemadeformacoherente. Losparadigmasdeprogramacinllenanesehueco,proporcionandoguastantosobrecmorealizarla abstraccindelosdatoscomosobreelcontroldelaejecucin.Esdecir,losparadigmasdeprogramacinson herramientasconceptualesparaanalizar,representaryabordarlosproblemas,presentando sistematizacionesalternativasocomplementariasparapasardelespaciodelosproblemasaldelas implementacionesdeunasolucin. Esmuyrecomendableyproductivocomprenderelenfoquededistintosparadigmas,puestoquepresentan estrategiasalternativas,incrementandonuestrasherramientasdisponiblesyhacindonoreflexionarsobre muchasdelastareasquerealizamosalcrearunprograma.Adems,amenudoocurrequeunosproblemasse formulandeformamuyclarasiselosanalizasegnunaperspectivadeterminada,mientrasqueproducenuna grancomplejidadvistosdeotramanera.

Algunosparadigmashabituales
Algunasdelasformasdepensarlosproblemasquehallegadoasistematizarsecomoparadigmasde programacinson: Laprogramacinmodular:Losprogramasseformanporpartesseparadasllamadasmdulos.Estos funcionandeformaindependienteentres,oserelacionanatravsdeinterfacesbiendefinidas.

Laprogramacinprocedural:Unprogramasecomponedeprocedimientos(subrutinas,mtodoso funciones)quesonfragmentosdecdigoquepuedenllamarsedesdecualquierpuntodelaejecucin deunprograma,includosotrosprocedimientosolmismo.(ej.ALGOL) Laprogramacinestructurada:Sepuedeexpresarcualquierprogramautilizandonicamentetres estructurasdecontrol:secuencial,condicionaleiterativa.Losprogramassecomponendepartes menoresconunnicopuntodeentrada,ysetratadeaislarlosparaevitarlacomplejidadque introducenlosefectoscolaterales.(ej.Pascal,C,Ada) Laprogramacinimperativa:Unprogramasepuededefinirentrminosdeestado,ydeinstrucciones secuencialesquemodificandichoestado.(ej.C,BASIC) Laprogramacindeclarativa:Esposibleexpresarunprogramaatravsdecondiciones,proposicioneso restricciones,apartirdelosqueseobtienelasolucinmediantereglasinternasdecontrol.(ej. PROLOG) Laprogramacinfuncional:Sepuedeexpresarunprogramacomounasecuenciadeaplicacindefunciones. Eludeelconceptodeestadodelcmputoynoprecisadelasestructurasdecontroldelaprogramacin estructurada.(ej.LISP,Haskell) Laprogramacinorientadaaobjetos:Losprogramassedefinenentrminosdeclasesdeobjetosquese comunicanentresmedianteelenvodemensajes.Esunaevolucindelosparadigmasdela programacinprocedural,estructuradaymodular,yseimplementaenlenguajescomoJava, Smalltalk,PythonoC++.

Programacinmultiparadigma
Losparadigmasdeprogramacinsonidealizaciones,y,comotales,nosiempresepresentandeforma totalmentepura,nisiempreresultanincompatiblesentres.Cuandoseentremezclandiversosparadigmasse produceloqueseconocecomoprogramacinmultiparadigma. Elusodedistintosmodelos,segnseadaptenmejoralasdiversaspartesdeunproblemaoanuestraformade pensamiento,resultatambinmsnaturalypermiteexpresardeformamsclarayconcisanuestrasideas. Algunoslenguajes,comoHaskelloPrologestndiseadosparaencajarperfectamenteenlavisindeun paradigmaparticular,mientrasqueotros,comopython,seadaptanespecialmentebienalaprogramacin multiparadigmaydangranlibertadalahoraderesolverunproblema,alnoimponenunmismopatrnpara todosloscasos.

Tiposdedatos
Unaformadealmacenaryrepresentarunafechaenunprogramapodraserlasiguiente: d = 14 m = "Noviembre"

a = 2006 def dime_fecha(dia, mes, anho): return "%i de %s de %i del calendario gregoriano" % (dia, mes, anho) print fecha(d, m, a) paraobtenerlasiguientesalida: "14deNoviembrede2006" Enesteejemplo,pararepresentarymanipularloqueconceptualmenteentendemoscomounafecha,seutilizan lasvariablesd,myacomoalmacenesdedatos,yunprocedimientoofuncin,denombredime_fecha,para realizarlarepresentacindelafechaalmacenada. Lasvariablespermitenalmacenartiposdedatosconcretoscomolosenteros(dya)olascadenasdetexto(m),y lafuncinrealizasutrabajodevolviendootrotipoconcreto,unacadenadetexto. Unodelosproblemasdeesteenfoqueesquenoreflejademasiadobienelconceptofechaqueusamoscomo modelomentalalimplementarlocomounconjuntodetresvariablesnorelacionadasentres(d,mya).Esdecir, lastresvariablestienenunaunidadconceptualennuestramente,quenosereflejaenlaformadeexpresarel problema.Delamismamanera,lafuncindime_fechadesconoceigualmentelarelacinentresusparmetros, quepodrasertotalmentearbitraria. Estasituacin,quepuedeparecerunacuestindeestilo,implicaunriesgodeproblemasdesincronizacin entrevariablesrelacionadas,dispersinendistintaspartesdelcdigodemanipulacionesquesonrelevantesal conjunto,prdidadelvalorsemnticodecadavariablequepuededarlugaraerroresaltransformarelcdigo Unejemplodedesconexinsemnticaentrelaimplementacinyelconceptoesquedpuedesercualquiervalor entero,mientrasqueundatieneunvalorsituadoentre1y31,mesunacadenadetextodentrodeunnmero limitadodeopciones,oanopuedetomarvaloresnegativos.Porsupuestoqueestosepodrasolucionarcon cdigoquehiciesecomprobacionesadicionales,peroenestecasoqueremosresaltarcmounprogramaesun modeloaproximadoaunproblemaycmoserapreferiblequelaimplementacinpudieserepresentardeforma msajustadaelcomportamientodelmodeloelegido. Unaposiblesolucinseradisponerdeuntipodedatosquerepresentedeformamsadecuadaelconceptode fechayquenospermitamanipularfechasdelamismamaneraquemanipulamosnmerosenteros,nmeros realesocadenasdetexto,independientementedelaimplementacininternaquelossustente.

Clasesyobjetos
Alenunciaralgunostiposdeparadigmashemosvistoquelaprogramacinorientadaaobjetosdefinelos programasentrminosdeclasesdeobjetosquesecomunicanentresmedianteelenvodemensajes.En esteapartadoaclararemosquseentiendeenesecontextoporclasesyobjetos. Lasclasessurgendelageneralizacindelostiposdedatosypermitenunarepresentacinmsdirectadelos conceptosnecesariosparalamodelizacindeunproblemapermitiendodefinirnuevostiposalusuario. Lasclasespermitenagruparenunnuevotipolosdatosylasfuncionalidadesasociadasadichosdatos, favoreciendolaseparacinentrelosdetallesdelaimplementacindelaspropiedadesesencialesparasuuso.A

estacualidad,denomostrarmsquelainformacinrelevante,ocultandoelestadoylosmtodosinternosdela clase,esconocidacomoencapsulacin,yesunprincipioheredadodelaprogramacinmodular. Unaspectoimportanteenelusodeclasesesquenosemanipulandirectamente(salvoenloqueseconoce comometaprogramacin),sinoquesirvenparaladefinicinnuevostipos.Unaclasedefinepropiedadesy comportamientoquesemuestranenlosentesllamadosobjetos(oinstanciasdeunaclase).Laclaseacta comomoldedeunconjuntodeobjetos,delosquesedicequepertenecenalaclase. Trasladandoestosconceptosalosnmerosenteros(tipoint),sepuededecirquelasvariablesquealmacenan nmerosenterossonobjetosoinstanciasdelaclaseintoquepertenecenalaclaseint. Entrminosmsabstractos,podemospensarenlasclasescomodefinicionesyenlosobjetoscomoexpresiones concretasdedichasdefiniciones.

Fisonomadeunaclase
Enpython,elesquemaparaladefinicindeunaclaseeselsiguiente: class NombreClase: <instruccin_1> ... <instruccin_n> endondeclassesunapalabrareservadaqueindicaladeclaracindeunaclase,NombreClaseunaetiquetaque danombrealaclasey,losdospuntos,quesealaneliniciodelbloquedeinstruccionesdelaclase. Elcuerpodeinstruccionesdelaclasepuedecontenertantoasignacionesdedatoscomodefinicionesde funciones.Estebloquedeinstruccionesseencuentraenelnuevoespaciodenombresconelnombredelaclase, quesegenera,asuvez,conlacreacindecadaobjeto.Enamboscasos,enelespaciodenombresdelaclasey delobjeto,esposibleaccederaloselementosquelointegranusandoeloperadorpunto,comoenelcasodelos espaciosdenombresdeunmdulo(e.j.math.pi,objeto.dato,objeto.funcion()). Silaprimerainstruccindelcuerpodelaclaseesunacadenadetexto,staseusacomocadenade documentacindelaclase. Nuestroejemplopodrareescribirseentrminosdeunaclaseas: class Fecha: "Ejemplo de clase para representar fechas" dia = 14 mes = "Noviembre" anho = 2006 def dime_fecha(self): return "%i de %s de %i" % (Fecha.dia, Fecha.mes, Fecha.anho) mi_fecha = Fecha() print mi_fecha.dia, mi_fecha.mes, mi_fecha.anho print mi_fecha.dime_fecha()

EnelfragmentodecdigoanteriordefinimoslaclaseFechayellaasignamosvaloresalasetiquetasdia,mesy anho(atributosdelaclase),ydefinimosunafuncin(unmtododelaclase),dime_fecha. Fueradeladefinicindelaclasecreamos(instanciamos)unobjetopertenecientealaclaseFecha.Esta instanciacinserealizautilizandolanotacindellamadaafuncin,ypodemosentenderlacomounallamadaa unafuncinquedevuelveunobjetodelaclaseFecha.Elobjetoobtenidoesasignadoalaetiquetami_fecha. Enlasiguientesinstruccionesmostramosporpantallalosvaloresdelaspropiedadesdia,mesyanhoyel resultadodelallamadaalmtododime_fecha,usandoeloperadorpuntoparaaccederalaspropiedadesy mtodosdelobjetomi_fecha,yaque,comohemosmencionadoantes,formanpartedelespaciodenombresdel objeto. Lallamadaalmtododime_fechanoincluyeningnparmetro,peropodemoscomprobarque,deforma contradictoria,ladeclaracindelmtodoindicauno,self.Esteparmetroesaadidoautomticamenteporel intrpreteenlasllamadasalosmtodosdeunaclase,ycontieneunareferenciaalobjetoquerecibelaseal(el querecibeunallamadaaunmtodo).selfpermiteaccederalaspropiedadesymtodosdeunobjetoconcretoy aclararemossusignificadoyusomsadelante.Porahoranosbastasaberqueesnecesarioincluirselfcomo primerparmetrodelosmtodosdefinidosenunaclaseyquenoesprecisoincluirelparmetroimplcito selfalrealizarllamadasaunmtodoatravsdelobjetoalquepertenece. Enrealidad,enelejemploanterior,lallamadami_fecha.dime_fecha()esunaformamscmodadeescribir (azcarsintctico)Fecha.dime_fecha(mi_fecha),loqueexplicalapresenciadelparmetro.

Unpaseoentreobjetos
Hastaelmomentohemosvistocmolasclasesdefinenlosdatos(oestado)ycomportamientodelosobjetosa travsdeatributos(opropiedades)ymtodos. Ahoravamosahacerunrecorrido,utilizandounasesininteractivadelintrpreteylascapacidadesde introspeccindepython,paraexplicarelusoyelcomportamientodelosobjetos. Veremosalgunascaractersticasdelosobjetos: Identidad.Losobjetossediferencianentres,deformaquedosobjetos,creadosapartirdelamismaclasey conlosmismosparmetrosdeinicializacin,sonentesdistintos. Definensucomportamiento(yoperarsobresusdatos)atravsdemtodos,equivalentesafunciones. Definenoreflejansuestado(datos)atravsdepropiedadesoatributos,quepuedensertiposconcretosu otrosobjetos. Pasamosaverunasesininteractivadelintrprete: >>> mi_fecha = Fecha()

>>> mi_fecha_2 = Fecha() >>> mi_fecha is mi_fecha_2 False >>> print mi_fecha <__main __.Fecha instance at 0x00B184B8> >>> print mi_fecha_2 <__main __.Fecha instance at 0x00B18328> Vemosquetantomi_fechacomomi_fecha_2soninstanciasdelaclaseFecha(enelmdulo__main__)ycada unatienesupropioespaciodememoriaindependiente. >>> print mi_fecha.dime_fecha() 14 de Noviembre de 2006 >>> print mi_fecha.dia 14 >>> print mi_fecha_2.dia 14 >>> Fecha.dia = 16 >>> print Fecha.dia 16 >>> print mi_fecha.dia 16 >> print mi_fecha_2.dia 16 >>> mi_fecha.dia = 30 >>> print Fecha.dia 16 >>> print mi_fecha.dia 30 >>> print mi_fecha_2.dia 16 Esteltimoexperimentoobservamoscmo,peseaquemi_fechaymi_fecha_2sondosinstanciasdistintasdela claseFecha,ambashacenreferenciaatravsdesuatributodiaalmismovalordelaclaseFecha.dia.Sin embargo,cuandoseproduceunaasignacinaeseatributo(aesaetiqueta,enrealidad)enunodelosobjetos vemoscmo,apartirdeentonces,eseobjetodisponedeunvalor'individual'asociadoalatributo. Esecomportamientorevelalaexistenciadeatributos(oestado)compartidosportodaslasinstanciasdeuna claseydeatributos(oestado)ligadosaunainstanciaparticular.Losprimerossesitanenelespaciode nombresdelaclase,yvemoscmosepuedenhacerasignacionesenlasesininteractivaanterior,olecturas,en elmtododime_fechadelejemploanterior.Lossegundossesitanenelespaciodenombresdecadaobjeto,y ahesdonderesultatilelparmetroself. Antesdeproseguir,podemosescudriarqusmbolossonaccesiblesyqucontienenlosespaciosdenombres delaclaseFechaydelosobjetosmi_fechaymi_fecha_2.Usamoslafuncindirparaloprimero,yelatributo __dict__paralosegundo,yaqueenpythonlosespaciosdenombresseimplementancomodiccionarios: >>> dir(Fecha) ['__doc__', '__module__', 'anho', 'dia', 'dime_fecha', 'mes'] >>> dir(fecha3) ['__doc__', '__module__', 'anho', 'dia', 'dime_fecha', 'mes'] >>> dir(fecha4) ['__doc__', '__module__', 'anho', 'dia', 'dime_fecha', 'mes'] Enlostrespodemosaccederalosmismossmbolos.Sinembargo... >>> Fecha.__dict__ {'__module__': '__main__', 'anho': 2006, 'dime_fecha': x00B176F0>, 'dia': 14, 'mes': 'Noviembre', '__doc__': 'Ejemplo de clase para representar fechas'} >>> mi_fecha_2.__dict__ {} >>> mi_fecha.__dict__ {'dia': 30} Elespaciodenombresdelaclaseeselquealbergalosnombresdelosatributosymtodosindicadosenla declaracindelaclase,ademsdelosatributosespeciales__doc__,quecontienelacadenadedocumentaciny

__module__,quecontieneelnombredelmduloalquepertenecelaclase.Esossmbolossonaccesibles tambinparalosobjetospertenecientesalaclase(talcomonosindicabadir()). Podemosvertambinqueelespaciodenombresdelobjetomi_fecha_2seencuentravaco,mientrasqueeldel objetomi_fechacontieneelatributoda.Estosedebeaqueanteriormenterealizamosunaasignacinal atributodiadelobjetomi_fecha(dndoleelvalor30).Elespaciodenombresrecogeesaversinparticulardel atributo,quenoapareceenelotroobjeto,puestoqueaccedealatributodeclase. Alosatributoscompartidosportodoslosobjetosdeunaclaseselosdenominaatributosdeclase,cuandose deseadiferenciarlosdelosatributosquepertenecenacadainstanciaenparticular.

Accesoindividualizadoaobjetos:self
Ahoraquehemosvistocmousaratributosdeclaseparacompartirdatosentretodoslosobjetosdeunamisma clase,tambinnosinteresaconocercmoutilizaratributoscomunesaunaclaseperoquepuedantomarvalores distintosparacadaunodelosobjetos. Retomamosahoraelmisteriosoparmetroselfquevimosestabapresentecomoprimerparmetrodetodoslos mtodosdeunaclase.Ensumomentoyacomentamosqueselfcontieneunareferenciaalobjetoquerecibela seal(elobjetocuyomtodoesllamado),porloquepodemosusaresareferenciaparaaccederalespaciode nombresdelobjeto,esdecir,asusatributosindividuales. >>> ... ... ... ... ... ... >>> >>> 5 >>> 5 >>> >>> 5 >>> 6 >>> 6 class F: i = 5 def dime_i(self): return F.i def dime_mi_i(self): return self.i a = F() a.dime_i() a.dime_mi_i() a.i = 6 a.dime_i() a.dime_mi_i() a.i

Enesteejemploelmtododime_iusaelatributodeclaseyretornasuvalor,5,mientrasqueelmtodo dime_mi_iusaunareferenciaalobjetoydevuelveelvalor6,elasignadoalatributodelobjetoa.Asaccedemos selectivamentealatributodeclaseioalatributodeinstanciai. Algoquepuedeaclararalgomslanaturalezadelparmetroself,esrecordarque,cuandohacemosunallamada aunmtodoun_metododeunobjetoun_objetopertenecientealaclaseUnaClase,elintrpretetraducela expresinun_objeto.un_metodo()comoUnaClase.un_metodo(un_objeto). Elusodeselfrespondealaformaparticularenquepythonimplementaelsoportedeobjetos,aunquelenguajes

comoJavaoC++utilizanmecanismossimilaresconlapalabrareservadathis.Enpythonselfnoesunapalabra reservadaycualquieretiquetausadacomoprimerparmetrovaldraigualmente,aunquesedesaconseja totalmenteelusodeotrasetiquetas,portratarsedeunaconvencinmuyarraigadaenellenguajequehaceel cdigomslegible,facilitaelresaltadodesintaxis,etc.

Elmtododeinicializacin__init__
Hemosvistoyacmodefiniryusaratributosdeclaseydeinstancia.Peroenpythonnoesnecesariala declaracindevariables,porloquecualquieratributoalqueserealiceunaasignacinenelcdigoseconvierte enunatributodeinstancia: >>> a = F() >>> a.i = 6 >>> a.atr = 3 >>> print a.atr 3 >>> a.__dict__ {'i': 6, 'atr': 3} Unafuncionalidadmuyconvenientequehemosvistoenladeclaracindeatributosdeclaseesladerealizarsu inicializacinenelcuerpodelaclase.Parapoderinicializarlosatributosdeunainstanciaexisteunmtodo especialquepermiteactuarsobrelainicializacindelobjeto.Dichomtodosedenomina__init__(condos guionesbajosalprincipioyalfinal)yadmitecualquiernmerodeparmetros,siendoelprimerolareferenciaal objetoqueesincializado(self,porconvencin),quenospermiterealizarlasasignacionesaatributosdela instancia.Estemtodoseejecutasiemprequesecreaunnuevoobjetodelaclase,traslaasignacinde memoriayconlosatributosdeclaseinicializados,ysecorrespondeparcialmenteconelconceptode constructordelaclaseexistenteenotroslenguajes. Conlareferenciaquenosproporcionaselfpodemosinicializaratributosdeinstancia,convalores predeterminadossilodeseamos,comoencualquierdefinicindefuncin: class Clase: def __init__(self, x=2): self.x = x self.a = x**2 self.b = x**3 self.c = 999 def dime_datos(self): return "Con x=%i obtenemos: a=%i, b=%i, c=%i" % (self.x, self.a, self.b, self.c) a1 = Clase(2) a1.dime_datos() a2 = Clase(3) a2.dime_datos() Salida: Conx=2obtenemos:a=4,b=8,c=999Conx=3obtenemos:a=9,b=27,c=999

PropiedadesyAtributos
Aunqueenlaterminologageneraldelaprogramacinorientadaaobjetosatributoypropiedadsepueden utilizarcomosinmimos,enpythonseparticularizaelusodepropiedadesparauntipoespecialdeatributos

cuyoaccesoseproduceatravsdellamadasafunciones. class ClaseC(object): def __init__(self): self.__b = 0 def __get_b(self): return self.__b def __set_b(self, valor): if valor > 10: self.__b = 0 else: self.__b = valor b = property(__get_b, __set_b, 'Propiedad b') c1 = ClaseC() print c1.b # b es 0 c1.b = 5 print c1.b # b es 5 c2 = ClaseC() print c2.b # b es 0 c2.b = 12 print c2.b #b es 0 Enesteejemplosedefinelapropiedadb,cuyocomportamientoes:cuandoserealizaunaasignacin,tomael valorentregadosiesmenorque10,o0encasocontrario,yloalmacenaenunatributoprivado__b.Cuandose producelalecturadeb,devuelveelvalorguardadoenelatributoprivado. EnPython,parapoderusarpropiedadesenunaclaseesnecesariohacerladerivardelaclaseobjectdeahque aparezcaalladodelnombredelaclaseClaseC.Enunapartadoposteriorseexplicarenquconsistela derivacindeclases. Lasignaturadelafuncinproperty,quedefineunapropiedaddelaclaseeslasiguiente:nombre_propiedad= property(get_f,set_f,del_f,doc)dondeget_feslafuncinllamadacuandoseproducelalecturadelatributo; set_flafuncinllamadacuandoseproduceunaasignacinalatributo;del_flafuncinllamadacuandose eliminaelatributo,ydocesunacadenadedocumentacindelapropiedad. Laspropiedadesresultanmuytilespararealizarlavalidacindelosvaloresasignados,latransformacino clculodevaloresdevueltosy,adems,dotandegranflexibilidadalahoradeescribirelcdigo,puestoquees posibleempezarusandoatributosyluegosustituirloporunapropiedadquerealicefuncionesadicionales,a medidaqueelcdigolorequieraysimplementecambiandoelcdigodelaclase,sinafectaralcdigoclientede laclase.

Herenciayderivacindeclases
Vemosqueelusodeclaseshacemsadecuadalarepresentacindeconceptosennuestrosprogramas. Adems,esposiblegenerarunaclasenuevaapartirdeotra,delaquerecibesucomportamientoyestado (mtodosyatributos),adaptndolosoamplindolossegnseanecesario.

Deunaclasequerepresentaseelconceptodevehculopodramosderivarotraspararepresentarautomviles, bicicletas,barcosoaviones,dondecadaunodeellosmantieneatributosymtodoscomunes(peso,color, velocidadmxima,nmerodepasajeros),mientrasqueotrossonexclusivos(nmeroderuedas,nmerode hlices,nmerodereactores,altitudmximadevuelo...). Entrminosmatemticospodemosexpresarlodiciendoqueesposibleestablecerrelacionesdepertenencia entreclases.SitenemosunaclaseAydeelladerivamosunaclaseB,podemosdecirque"BesunaA",oque"Bes unaespecializacindeA". EnlaterminologadelaPOOsediceque"BheredadeA","BesunaclasederivadadeA","AeslaclasebasedeB", "AessuperclasedeB"o"AesclasemadredeB". Estofacilitalareutilizacindelcdigo,puestoquesepuedenimplementarloscomportamientosydatosbsicos enunaclasebaseyespecializarlosenlasclasesderivadas. Enunprogramahipotticoquetrabajaseconformasgeomtricas,podramostenerunaclasebaseFormay clasesderivadasdeellacomoTriangulo,Cuadrado,Circulo...Enlaclasebasepodramosdefinirunmtododibuja querepresentalafiguraenpantalla,yunmtodoareayotropermetroquecalculanelreayelpermetro, respectivamente. Enellenguajepython,paraexpresarqueunaclasederiva,desciendeoesherederadeotrauotrasclasesse aadetraselnombre,enladeclaracindelaclase,unatuplaconlosnombresdelasclasesbase. ElsiguienteejemplocreaunaClaseAydeelladerivaunaClaseBqueinicializaunatributoadicional,cambiael comportamientodeunmtodoyheredalosatributosdelaclasemadre: class ClaseA: def __init__(self, x): self.a = x self.b = 2 * x def muestra(self): print "a=%i, b=%i" % (self.a, self.b) class ClaseB(ClaseA): def __init__(self, x, y): ClaseA.__init__(self, x) self.c = 3 * (x + y) + self.b def muestra(self): print "a=%i, b=%i, c=%i" % (self.a, self.b, self.c) print "Objeto A" a = ClaseA(2) print a.__dict__ a.muestra() print "ObjetoB" b = ClaseB(2, 3) print b.__dict__ b.muestra()

Salida: ObjetoA {'a':2,'b':4} a=2,b=4 ObjetoB {'a':2,'c':19,'b':4} a=2,b=4,c=19 LaclaseClaseAmuestrafuncionalidadesqueyahemosidoviendoenestaintroduccin(atributosdeinstanciaa yb,mtodomuestra).LaclaseClaseBsedeclaracomodescendientedelaClaseA,porloqueheredasus mtodosyatributosymodificaalgoelcomportamientodelaclasemadre.Porunaparte,ensumtodode inicializacinllamaalmtododelaclasemadreconlosparmetrosdeseados,y,posteriomente,aadeun nuevoatributodeinstanciaquenoexisteenlaclasemadre.Porotrolado,redefineunmtodoexistenteen ClaseA,cambiandolaimplementacin. Estaltimatcnica,enlaqueunmismonombreseasociaacomportamientosdistintosseconocecomo polimorfismo,ysehabladequeelmtodosehasobrecargado,esdecir,seleasignandistintossignificadosen funcindesucontexto.Elpolimorfismotambinaludealaposibilidaddeutilizar,enuncontextoenelquese esperaunaclasedada,cualquierclasederivada.

Laclaseobject
Desdelaversin2.2depython,sehaestablecidounaclasebasellamadaobjectdelaqueseaconsejaderivar todaslasclases.Estopermiteaprovecharunaseriedecaractersticassloexistentesenlas"nuevasclases" (comoladefinicindepropiedades),quesedescribenenladocumentacindepython. Enelejemplosobreelusodepropiedadesseintrodujolaherenciasinexplicarla,derivandolaclasedeobject. Ahoradeberaestarmsclaralarazn.

Jerarquasdeclases
Laherenciapermiteestablecerrelacionesentreclases,y,estasrelacionesdepertenenciapuedenseravarios niveles,yramificarseenloquesedenominanjerarquasdeclases. Unejemplodeclsicoparavisualizarlasjerarquasdeclaseseselquepodraservirparamodelizarelconjuntode empleadosdeunaempresa.EnellaapareceunaclasebaseEmpleado,quedisponedelosatributosnombrey departamento;deelladesciendenlassubclasesGestor(atributoadicionalinformes)yTrabajador(atributo adicionalproyectos),ydeestaltimaderivanlasclasesComercial(atributoadicionalparticipacin)eIngeniero (atributooriginalarea). Grficamentepodrarepresentarsedelasiguientemanera:

Eneldiagramasepuedeverennegritalosatributosqueimplementacadaclase,yengrislosqueheredade clasesmadre.Elcdigo(bsicodeinicializacin)delasclasespodraserelsiguiente: class Empleado: def __init__(self, nombre, departamento="general"): self.nombre = nombre self.departamento = departamento class Gestor(Empleado): def __init__(self, nombre): Empleado.__init__(self, nombre) self.informes = [] class Trabajador(Empleado): def __init__(self, nombre): Empleado.__init__(self, nombre) self.proyectos = [] class Comercial(Trabajador): def __init__(self, nombre, participacion=0.1): Trabajador.__init__(self, nombre) self.departamento = "ventas" self.participacion = participacion class Ingeniero(Trabajador): def __init__(self, nombre, area="mecnica"): Trabajador.__init__(self, nombre) self.departamento = "ingeniera" self.area = area Naturalmente,cadaunadelasclasestendrasuspropiosmtodosquedefinirancomportamientospropiosde cadaclaseosubclase,quenosehandetalladoenelejemplo. Unaalternativaalaherenciaeslacomposicin,enelqueunaclasesecomponedeotrasclasesinternas,yque puedeserunamejoralternativaenmuchoscasos.

Encapsulacinygradosdeprivacidad
UnodelosprincipiosqueguanlaPOO,heredadosdelaprogramacinmodular,eseldeencapsulacin.Hemos

vistocmosepuedeagruparcomportamientoydatosgraciasalusodeobjetos,perohastaelmomento,tanto losatributoscomolosmtodosquesedefinenenlasclasescorrespondientesseconviertenenmtodosy atributosvisiblesparalosusuariosdelaclase(laAPIdelaclase). Sedicequeunmtodooatributoespblicosiesaccesibledesdeelexteriordelaclase,mientrasquese denominaprivadoencasocontrario. Esdeseablepodersealarqumtodosyatributosnodebenutilizarsefueradelaclaseparaevitarexponer excesivamentelosdetallesdelaimplementacindeunaclaseounobjeto. Pythonutilizaparaelloconvencionesalahoradenombrarmtodosyatributos,deformaquesesealesu carcterprivado,parasuexclusindelespaciodenombres,oparaindicarunafuncinespecial,normalmente asociadaafuncionalidadesestndardellenguaje. _nombre Losnombresquecomienzanconunnicoguinbajoindicandeformadbilunusointerno.Adems,estos nombresnoseincorporanenelespaciodenombresdeunmduloalimportarlocon"from...import*". __nombre Losnombresqueempiezanpordosguionesbajosindicansuusoprivadoenlaclase. Porejemplo,enladefinicindeclasesiguiente: class ClaseA: def __init__(self, a) self.__a = a self.x = self.__a**2 + 2 self.y = self.__a**3 + 3 elatributo__aesdeusointernodelaclaseynoseexportadirectamente.Acontinuacinpodemosvercmo tratalosatributos'privados'python: >>> a = ClaseA(2) >>> dir(a) ['_ClaseA__a', '__doc__', '__init__', '__module__', 'x', 'y'] >>> a.__dict__ {'x':6, 'y':11, '_ClaseA__a':2} Todavaesposibleaccedera__a,peroelnombreestransformadoa'_ClaseA__a',quelosealacomoun atributodeusoprivado. __nombre__ Losnombresqueempiezanyacabancondosguionesbajosindicanatributos"mgicos",deusoespecialyque residenenespaciosdenombresquepuedemanipularelusuario.Solamentedebenusarseenlamaneraquese describeenladocumentacindepythonydebeevitarselacreacindenuevosatributosdeestetipo.

Algunosejemplosdenombres"singulares"deestetiposon:__init__,mtododeinicializacinde objetos__del__,mtododedestruccindeobjetos__doc__,cadenadedocumentacindemdulos, clases...__class__,nombredelaclase__str__,mtodoquedevuelveunadescripcindelaclasecomocadena detexto__repr__,mtodoquedevuelveunarepresentacindelaclasecomocadenadetexto__module__, mduloalquepertenecelaclaseSepuedeconsultarlalistadeatributosdeestetipoysudescripcindetallada enladocumentacindepython.

Resmenfinal
Laprogramacinorientadaaobjetosenuncialaposibilidaddeescribirunprogramacomounconjuntodeclases deobjetoscapacesdealmacenarsuestado,yqueinteractanentresatravsdelenvodemensajes. Lastcnicasmsimportantesutilizadasenlaprogramacinorientadaaobjetosson: Abstraccin:Losobjetospuedenrealizartareas,interactuarconotrosobjetos,omodificareinformarsobre suestadosinnecesidaddecomunicarcmoserealizandichasacciones. Encapsulacin(uocultacindelainformacin):losobjetosimpidenlamodificacindesuestadointernoola llamadaamtodosinternosporpartedeotrosobjetos,ysolamenteserelacionanatravsdeuna interfazclaraquedefinecmoserelacionanconotrosobjetos. Polimorfismo:comportamientosdistintospuedenestarasociadosalmismonombre Herencia:losobjetosserelacionanconotrosestableciendojerarquas,yesposiblequeunosobjetoshereden laspropiedadesymtodosdeotrosobjetos,extendiendosucomportamientoy/oespecializndolo. Losobjetosseagrupanasenclasesqueformanjerarquas. Lasclasesdefinenelcomportamientoyestadodisponiblequeseconcretaenlosobjetos. Losobjetossecaracterizanpor: Teneridentidad.Sediferencianentres. Definirsucomportamientoatravsdemtodos. Definiroreflejarsuestadoatravsdepropiedadesyatributos.

Das könnte Ihnen auch gefallen