Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas
Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari
Programacin Orientada a Objetos con Python Tabla de contenidos Conceptos Generales........................................................................................................2 El paradigma orientado a objetos...............................................................................2 Clase..............................................................................................................................2 Objeto (Instancia).........................................................................................................2 Propiedades..................................................................................................................3 de Clase.....................................................................................................................3 de Instancia..............................................................................................................3 Mtodos.........................................................................................................................3 El parmetro sel!...................................................................................................3 "obrecarga de operadores.......................................................................................# Constr$ctor % &estr$ctor.........................................................................................' Getter ( "etter ( &eleter.............................................................................................' Caracter)sticas *$ndamentales........................................................................................+ Encaps$lamiento..........................................................................................................+ ,erencia........................................................................................................................+ ,erencia M-ltiple..................................................................................................... Orden de /esol$ci0n de Mtodos............................................................................. Polimor!ismo..............................................................................................................12 " Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari Conceptos Generales 3a programaci0n orientada a objetos (POO) es $n paradigma de programaci0n 4$e representa conceptos en $na estr$ct$ra denominada clase5 4$e integra a las propiedades (datos) 4$e describen al concepto5 % a los procedimientos asociados5 conocidos como mtodos. 3os objetos se crean a partir de las clases5 % p$eden interact$ar entre s) mediante mensajes. "e p$ede considerar a $n objeto como comp$esto de s$stanti6os (6ariables) % 6erbos (!$nciones). "malltal75 C885 Objecti6e9C5 C:5 ;a6a5 ;a6ascript % P%t<on son s0lo alg$nos ejemplos de leng$ajes de programaci0n orientados a objetos. #l $aradigma orientado a o%&etos =n programa orientado a objetos p$ede 6erse como $na colecci0n de objetos 4$e interact-an entre s)5 en oposici0n a la 6isi0n del modelo con6encional5 en la 4$e se 6e $n programa como $na lista de tareas (s$br$tinas) para lle6ar a cabo. class MiClase: # Definicin de una clase def MiMetodo(self): # Definicin de un mtodo ('self' representa un objeto) self.MiPropiedad = "Mi Dato" # Definicin de una propiedad de objeto MiObjeto = MiClase() # Instanciacin de una clase MiObjeto.MiMetodo() # Ejecucin de un mtodo print MiObjeto.MiPropiedad # Obtencin de la propiedad de un objeto Cada objeto es capa> de recibir mensajes5 procesar datos5 % en6iar mensajes a otros objetos5 como si se tratara de $na ?m4$ina@ o caja negra5 independiente5 con $n papel distinto o $na responsabilidad -nica. Aanto los datos (llamados propiedades) como las acciones sobre esos datos (llamadas mtodos) estn estrec<amente asociados con el objeto correspondiente. Clase =na clase es $n modelo o plantilla 4$e describe $n tipo de objeto. El intrprete o compilador $tili>a la clase cada 6e> 4$e se tenga 4$e crear $n n$e6o objeto. Este proceso se llama instanciacin. Cada objeto es $na instancia de alg$na clase. '%&eto (Instancia) =n objeto es $na entidad de programaci0n 4$e contiene propiedades % mtodos5 de ac$erdo a $n modelo de!inido al 4$e se denomina clase. Cada objeto tiene $na identidad (nombre o identi!icador)5 $n estado (datos o propiedades) % $n comportamiento (acciones o mtodos). * Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari Pro$iedades 3as propiedades p$eden ser de clase o de instanciaB class OtraClase: PropiedadClase = 0 def __init__(self, n): # Mtodo constructor de la clase self.PropiedadObjeto = n Objeto1 = OtraClase(1) # Instancia 1: Inicialia la propiedad de Objeto1 Objeto2 = OtraClase(2) # Instancia !: Inicialia la propiedad de Objeto! print Objeto1.PropiedadClase # Imprime: " print Objeto1.PropiedadObjeto # Imprime: 1 print Objeto2.PropiedadClase # Imprime: " print Objeto2.PropiedadObjeto # Imprime: ! OtraClase.PropiedadClase = # Modifica la propiedad de la clase print Objeto1.PropiedadClase # Imprime: # print Objeto2.PropiedadClase # Imprime: # de Clase =na propiedad de clase es a4$ella c$%o estado es compartido por todas las instancias de la clase. de Instancia =na propiedad de instancia es a4$ella c$%o estado p$ede ser in6ocado o modi!icado -nicamente por la instancia a la 4$e pertentece. +todos =n mtodo es $na !$nci0n5 procedimiento o s$br$tina 4$e !orma parte de la de!inici0n de $na clase. 3os mtodos5 mediante s$s parmetros de entrada5 de!inen el comportamiento de las instancias de la clase asociada. El parmetro "self" 3a palabra self representa a la instancia de una clase5 es decir5 a $n objeto. "e $tili>a dentro de la clase para <acer re!erencia a las propiedades del objeto en s) % di!erenciarlas de las de la propia clase. class Persona: def __init__(self, no!bre): self.no!bre = no!bre def sal"dar(self): print "#ola, !i no!bre es", self.no!bre def __del__(self): print "$s di%e adi&s." $ self.no!bre , Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari %arlos = Persona("Carlos 'a(as") %arlos.sal"dar() En el ejemplo5 no!bre es $n atributo o parmetro del mtodo __init__5 mientras 4$e self.no!bre es $na propiedad de instancia. Sobrecarga de operadores Consiste en la posibilidad de contar con mtodos del mismo nombre pero con comportamientos di!erentes. class )ista: def __init__(self): self.ite!s = *+ def __str__(self): return ,\n,.join(self.ite!s) def __repr__(self): return repr(self.ite!s) def a-re-ar(self, ite!): self.ite!s.append(str(ite!)) def .a%iar(self): self.ite!s = *+ def .a%io(self): return self.ite!s == *+ def %antidad(self): return len(self.ite!s) class /r%0i.o: def __init__(self, no!bre=,lista.t1t,): self.ite!s = open(no!bre).readlines() if os.pat0.e1ists(no!bre) else *+ self.ite!s = * ite!.strip() for ite! in self.ite!s + # $impia la lista self.no!bre = no!bre def __del__(self): open(self.no!bre, ,2,).2rite(,\n,.join(self.ite!s)) class )ist/r%0(/r%0i.o, )ista): pass lista = )ist/r%0() lista..a%iar() lista.a-re-ar(,#ola,) lista.a-re-ar(2) lista.a-re-ar((, 3)) lista.a-re-ar(,C0a",) print "Cantidad:", lista.%antidad(), ,\n, print lista print ,\n)ista:,,repr(lista) En los ejemplos anteriores5 __init__ % __str__ son redefiniciones de mtodos predefinidos 4$e modi!ican parte del comportamiento estndar de los objetos5 en - Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari este caso la constr$cci0n % la impresi0n del objeto5 respecti6amente. C esta capacidad del leng$aje se le denomina sobrecarga. Constructor y Destructor En P%t<on5 los mtodos __init__ % __del__ son lo 4$e se conoce como mtodo constructor % destructor respecti6amente. Do es obligatorio incl$irlos c$ando de!inimos $na clase5 pero como se 6er a contin$aci0n5 p$eden ser de m$c<a $tilidad5 % a men$do son necesarios. El mtodo constructor de $na clase se ejec$ta en cada instanciaci0n de la clase5 es decir5 d$rante el proceso de creaci0n de $n objeto. El mtodo destructor de $na clase se ejec$ta c$ando el objeto %a no es re!erenciado dentro del programa5 o simplemente c$ando el proceso termina. /ecordemos 4$e $n proceso es $n programa en ejec$ci0n5 % d$rante s$ !inali>aci0n5 se borran de la memoria todos los objetos creados5 lo 4$e acti6a el mtodo destructor correspondiente a cada $no de ellos. Getter / Setter / Deleter 3as propiedades5 tanto las de clase como las de instancia5 se p$eden acceder directamente $tili>ando la sintaEis ?p$nto@ (objeto.propiedad). "in embargo5 se recomienda 4$e c$al4$ier operaci0n relacionada con propiedades se realice mediante mtodos especiales5 denominados getters % setters (obtenedores % colocadores). Opcionalmente5 tambin p$ede de!inirse $n deleter (borrador). Estos mtodos especiales son necesarios principalmente para el manejo de las propiedades ms importantes del objeto5 generalmente a4$ellas 4$e necesitan ser accedidas desde otros objetos5 no precisamente desde los mtodos propios del objeto. Do es obligatorio de!inir getters % setters para todas las propiedades5 sino s0lo para a4$ellas en las 4$e necesitemos alg-n tipo de 6alidaci0n pre6ia antes de obtener o colocar el 6alor in6ol$crado. En P%t<on contamos con dos maneras de de!inir estos mtodos especialesB # Ejemplo 1: %uncin 'propert&' class 4je!plo1(obje%t): def __init__(self): self._1 = 5one def -et1(self): return self._1 def set1(self, .alor): self._1 = .alor . Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari def del1(self): del self._1 1 = propert((-et1, set1, del1, "6o( la propiedad ,1,.") # Ejemplo !: Decoradores (''(((') class 4je!plo2(obje%t): def __init__(self): self._1 = 5one 7propert( def 1(self): "6o( la propiedad ,1,." return self._1 71.setter def 1(self, .alor): self._1 = .alor 71.deleter def 1(self): del self._1 Cmbas sintaEis c$mplen el mismo prop0sito % dan eEactamente los mismos res$ltados5 pero la seg$nda es la ms n$e6a incorporaci0n al leng$aje P%t<on. Aambin contamos con los mtodos __-etite!__ % __setite!__ para manip$lar listas %(o diccionarios $sando -nicamente el nombre del objeto. &e esta manera5 en 6e> de escribir objeto.lista*indi%e+ simplemente podemos escribir objeto*indi%e+. EjemploB class Di%: def __init__(self): self.di% = 89 def __repr__(self): return repr(self.di%) def __-etite!__(self, %la.e): return self.di%.-et(%la.e, 5one) def __setite!__(self, %la.e, .alor): self.di%*%la.e+ = .alor &e esta manera5 $na instancia de la clase Di% p$ede $sarse como si se tratase de $n diccionarioB d = Di%() d*,5o!bre,+ = ,Carlos, print d*,5o!bre,+ / Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari Caractersticas Fundamentales #nca$sulamiento Consiste en colocar al mismo ni6el de abstracci0n a todos los elementos (estado % comportamiento) 4$e p$eden considerarse pertenecientes a $na misma entidad (identidad). Esto permite a$mentar la co<esi0n de los componentes del sistema. class Persona(obje%t): def __init__(self, no!bre): self.set5o!bre(no!bre) def -et5o!bre(self): return , ,.join(self.__no!bre) def set5o!bre(self, no!bre): self.__no!bre = no!bre.split() no!bre = propert((-et5o!bre, set5o!bre) 3as propiedades pertenecen al espacio de nombres del objeto (namespace) % p$eden estar oc$ltas5 es decir5 s0lo accesibles para el objeto. En P%t<on5 esto -ltimo se logra s$per!icialmente anteponiendo dos g$iones bajos ( FF ) al nombre de la propiedad. %arlos = Persona("Carlos 'a(as") print %arlos.no!bre."pper() %arlos.no!bre = ,Carlos /. 'a(as :., print %arlos.no!bre."pper() &ecimos 4$e en P%t<on se logra s0lo s$per!icialmente el oc$ltamiento de las propiedades por4$e5 si bien no podemos in6ocar la propiedad no!bre de manera tradicional5 s) podemos <acerlo de la sig$iente maneraB print %arlos._Persona__no!bre 0erencia 3as clases se relacionan entre s) dentro de $na jerar4$)a de clasi!icaci0n 4$e permite de!inir n$e6as clases basadas en clases preeEistentes5 % as) poder crear objetos especiali>ados. class 4!pleado(Persona): def __init__(self, no!bre, %ar-o): Persona.__init__(self, no!bre) self.%ar-o = %ar-o print "$s es $s" $ (self.no!bre, self.%ar-o) 3a <erencia es el mecanismo por eEcelencia de la programaci0n orientada a objetos 1 Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari 4$e permite lograr la re$tili>aci0n de c0digo. Mediante ella5 podemos crear n$e6as clases modi!icando clases %a eEistentes. Herencia Mltiple C$ando la <erencia in6ol$cra a ms de $na clase5 <a% <erencia m-ltiple. El orden en el 4$e las clases son in6ocadas determina la pre6alencia de propiedades % mtodos de idntica denominaci0n en el ?rbol geneal0gico@. rden de !esoluci"n de M#todos El Orden de /esol$ci0n de Mtodos o M/O (Method Resolution Order) es la manera en 4$e $n leng$aje de programaci0n decide d0nde b$scar $n mtodo (o $na propiedad) en $na clase 4$e <ereda estos elementos de 6arias clases s$periores. 3a importancia del M/O se <ace patente en presencia de la <erencia m-ltiple donde5 ante dos elementos con la misma denominaci0n en clases distintas5 es necesario de!inir 4$ mtodo o propiedad pre6alecer en $na instanciaci0n. Figura 1: Diagrama de herencia en diamante En el caso de P%t<on5 la e6ol$ci0n del leng$aje dio como res$ltado dos algoritmos M/O distintos5 $no simple para las clases de estilo antig$o % otro ms so!isticado para las clases de estilo n$e6o (las 4$e <eredan de obje%t). Cmbos algoritmos pro6ienen de la teora de grafos5 % son los sig$ientesB DFS Depth First Search (G-s4$eda en pro!$ndidad)B /ecorre los nodos del gra!o (rbol) de i>4$ierda a derec<a empe>ando de la ra)> pero <asta el nodo ms lejano. En el diagrama5 empe>ando desde la clase &5 el orden ser)a &5 G5 C5 C. 2 Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari BFS Breadth First Search (G-s4$eda en anc<$ra)B /ecorre los nodos del gra!o e!ect$ando barridos de i>4$ierda a derec<a. En el diagrama5 empe>ando desde la clase &5 el orden ser)a &5 G5 C5 C. # )l*oritmo: D%+ , Dept- %irst +earc- (.us/ueda en profundidad) class /: 1 = ,a, class ;(/): pass class C(/): 1 = ,%, class D(;, C): pass print ,<iejo estilo: D.1 = "$s", $ D.1 # )l*oritmo: .%+ , .readt- %irst +earc- (.us/ueda en anc-ura) class /(obje%t): 1 = ,a, class ;(/): pass class C(/): 1 = ,%, class D(;, C): pass print ,5"e.o estilo: D.1 = "$s", $ D.1 <iejo estilo: D.1 = "a" 5"e.o estilo: D.1 = "%" El M/O p$ede obtenerse mediante mecanismos de introspecci0n5 como p$ede 6erse en la sig$iente sec$encia de sentencias ejec$tadas d$rante $na sesi0n con el intrprete interacti6o de P%t<onB Empecemos creando dos clases 6ac)as5 -nicamente a modo de ejemplo5 <aciendo $so de la sentencia comod)n passB === class ani!al(obje%t): pass ... === class perro(ani!al): pass ... Ccabamos de de!inir dos clasesB ani!al (de tipo obje%t) % perro5 4$e <ereda los mtodos % propiedades de ani!al. Cmbas clases aparentemente son ig$ales5 a ning$na de las dos se les de!inieron mtodos o propiedades espec)!icas5 pero se di!erencian en c$anto a la <erencia H $na deri6a de la otra. C contin$aci0n5 creamos $na instancia de la clase perro5 a la 4$e llamamos fido. === fido = perro() Mediante el mtodo __%lass__ % el operador is podemos 6er 4$e la clase del objeto fido es perro5 no ani!al5 a$n4$e ?desciende@ de ella. === fido.__%lass__ is ani!al >alse === fido.__%lass__ is perro ?r"e "in embargo5 con la !$nci0n isinstan%e5 6emos 4$e fido es $na instancia de la clase ani!al5 al ig$al 4$e de la s$b9clase perro. 3 Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari === isinstan%e(fido, ani!al) ?r"e === isinstan%e(fido, perro) ?r"e Por -ltimo5 el mtodo __!ro__ nos de6$el6e $na t$pla en la 4$e podemos 6er el orden de resol$ci0n de mtodosB === ani!al.__!ro__ (@class ,__!ain__.ani!al,=, @t(pe ,obje%t,=) === perro.__!ro__ (@class ,__!ain__.perro,=, @class ,__!ain__.ani!al,=, @t(pe ,obje%t,=) 3os mtodos % propiedades de $na clase se s$perpondrn a los de la clase s$perior en el orden 4$e aparecen en la t$pla. Polimorfismo Consiste en de!inir comportamientos di!erentes basados en $na misma denominaci0n5 pero asociados a objetos distintos entre s). Cl llamarlos por ese nombre com-n5 se $tili>ar el adec$ado al objeto 4$e se est in6ocando. a = Persona("Pablo") # 0ace 1ablo b = Persona("A"an") # 0ace 2uan print b # 2uan dice 34ola3 % = 4!pleado("4steban","C0ofer") # 0ace Esteban # Esteban es 5-ofer En el sig$iente ejemplo5 las dos clases deri6adas de /ni!al comparten el mtodo sonido5 pero cada $na le agrega s$ partic$laridad. class /ni!al: %antidad = 0 def __init__(self): print "#ola, so( "n ani!al." self.no!bre = "" /ni!al.%antidad B= 1 print "#a(", /ni!al.%antidad, "ani!ales." def sonido(self): print "4ste es !i sonido:" def __del__(self): print self.no!bre, "di%e: /diosC" class Perro(/ni!al): def __init__(self, no!bre): /ni!al.__init__(self) print "6o( "n perro." self.no!bre = no!bre print "Me lla!o", self.no!bre def sonido(self): /ni!al.sonido(self) "4 Universidad Nacional de Asuncin Facultad Politcnica Licenciatura en Ciencias Informticas Paradigmas de la Programacin Prof. Lic. Carlos A. Zaas !uggiari print ":"a"C" class :ato(/ni!al): def __init__(self, no!bre): /ni!al.__init__(self) print "6o( "n -ato." self.no!bre = no!bre print "Me lla!o", self.no!bre def sonido(self): /ni!al.sonido(self) print "Mia"C" fido = Perro(">ido") fido.sonido() to! = :ato("?o!") to!.sonido() 3os objetos fido % to! descienden de /ni!al pero cada $no ?emite s$ propio sonido@. ""