Programación Orientada a Objetos (POO)
(http://webquest.es/files/u21382/POO.jpg)
Fuente: http://frontendlabs.io/1305--tutorial-basico-de-python-parte-iv-programacion-orientada-a-objetos (http://frontendlabs.io/1305--tutorial-basico-de-python-parte-iv-programacion-orientada-a-objetos)
El Paradigma de la Programación Orientada a Objetos es:
Ver cada cosa como un objeto, con sus funciones y atributos, y que todo objeto proviene de una "plantilla" mayor (un molde, una "clase").
Propone modelar todo en base a clases y objetos. Este paradigma consiste en el uso de los conceptos de
herencia, cohesión, abstracción, polimorfismo, acomplamiento y encapsulamiento.
Lo primero: La clase
La clase es el molde de donde derivan otros objetos.
[Añadido]Para el nombre de una clase, siempre se debe de comenzar con mayuscula. Esto tiene un nombre:
Upper Camel Case (porque parece la espalda de un camello)
Ejemplo: Clase, Animal, Robot, etc...
Pero si el nombre de la clase es "complejo" (osea, si está compuesto por algunas palabras), entonces cada inicio de palabra comenzará en mayusculas:
Ejemplo: MiClase, AnimalBosque, EscanerPuertos, ClaseDeEjemplo, etc...
Citar
Por ejemplo si nos ponemos a pensar en gatos. ¿Cómo podemos reconocer que un gato es en si un gato y no un perro? Bueno, todo gato tiene ojos, nariz, boca, 4 patas, mucho pelo, una cola, orejas, dice miau, ronronea y tienen sus garras. Esto seria la plantilla del gato y con lo mencionado anteriormente también podemos imaginarnos uno. ¿Pero fuimos específicos en sus características? Cada uno de nosotros podemos pensar en un gato pero no sera el mismo. Cada uno hemos pensado en una instancia de un gato acorde a las características que hemos mencionado. Yo pude haber pensado en un gato gordo de pelaje rojo. Mientras que otro habrá pensado en un gato virtual de ojos grande de color naranja.
Usemos el ejemplo del gato.
Creamos una clase llamada gato:
class Gato:
def __init__(self):
print("Ha nacido un gato.")
def miau(self):
print("Miau!")
g = Gato() # Imprimirá "Ha nacido un gato."
g.miau() # Imprimirá "Miau!"
__init__
Lo primero:
Vemos ahí una función llamada __init__().
En otros lenguajes de programación puede llamarse "
constructor".
__init__()
es una función especial que siempre se ejecutará al ser instanciado un objeto. Además, sirve como constructora de variables (osea, aquí crearemos las variables que serán usadas en todas las funciones de la clase Gato).
Para esto, usamos una palabra especial:
self
class Gato:
def __init__(self, energia, hambre):
self.energia = energia
self.hambre = hambre
print("Un gato ha nacido!")
def miau(self):
print("Miau!")
Como podemos ver, __init__ recibe "3" variables: self, energía y hambre.
En funciones, gracias al atributo "self" es posible utilizar las variables declaradas en __init__ dentro de toda la clase.
Luego, tenemos 2 variables: energía y hambre. Estas variables serán enviadas a la clase a través del objeto instanciado.
Además, tenemos la función miau(). Y como sabemos, esta no se ejecutará hasta que nosotros la llamemos.Ahora, para
instanciar un objeto, hacemos lo siguiente:
g = Gato(5,3) # Imprimirá "Ha nacido un gato."
g.miau() # Imprimirá "Miau!"
g es un objeto de la clase Gato.
Podemos ver que al instanciar el objeto, le pasamos 2 numeros a la clase Gato: 5 y 3.
Estos numeros serán las variables energia y hambre que serán usadas en toda la clase.
Ahora,
g podrá usar las funciones que se encuentren en la clase. Para eso, usamos un punto, seguido del nombre de la función a llamar.
Entonces, añadimos más funciones a nuestra clase:
class Gato:
def __init__(self, energia, hambre):
self.energia = energia
self.hambre = hambre
print("Un gato ha nacido!")
def miau(self):
print("Miauuu!")
def tomar_leche(self, leche_en_litros):
self.hambre += leche_en_litros
print ("El gato toma su leche")
def acariciar(self):
print ("Prrrrr...")
def jugar(self):
if self.energia <= 0 or self.hambre <=1:
print ("El gato no quiero jugar")
else:
self.energia -=1
self.hambre -= 2
print ("Al gato le encanta jugar")
def dormir(self, horas):
self.energia += horas
print ("El gato tomo una siesta")
Instanciamos un objeto, y procedemos a ejecutar cada función:
gato = Gato(7,5)
gato.miau()
gato.tomar_leche(2)
gato.acariciar()
gato.jugar()
gato.dormir(4)
Citar
Un gato ha nacido!
Miauuu!
El gato toma su leche
Prrrrr...
Al gato le encanta jugar
El gato tomo una siesta
Nótese que
en la función jugar(), le restamos energía y hambre al gato, haciendo que en un determinado momento, el gato ya esté "cansado", y ya no quiera jugar.
gato = Gato(7,5)
for i in range(3):
gato.jugar()
Haciendo lo anterior,ejecutamos 3 veces la función jugar()
Y entonces...
Citar
Un gato ha nacido!
Al gato le encanta jugar
Al gato le encanta jugar
El gato no quiero jugar
Como vemos, al final, el gato "no quiere jugar", porque ya no tiene energías, o porque tiene hambre.
Para esto, solo hace falta ejecutar:
- dormir() --> Para recuperar energía.
- tomar_leche() --> Para tener menos hambre.
Herencia
(no, no hablo de dinero)
La Herencia es cuando una clase HEREDA de otra clase todo lo de ella (atributos, métodos...).Se puede decir que, es una clase extendida, ya que ella poseerá sus funciones, y además, poseerá todo lo que contenga la clase a heredar.
class Felino:
def __init__(self):
print("Ha nacido un felino!")
def rugido(self):
print("El felino dió un rugido.")
class Gato(Felino):
def __init__(self, energia, hambre):
self.energia = energia
self.hambre = hambre
print("Un gato ha nacido!")
def miau(self):
print("Miauuu!")
def tomar_leche(self, leche_en_litros):
self.hambre += leche_en_litros
print ("El gato toma su leche")
def acariciar(self):
print ("Prrrrr...")
def jugar(self):
if self.energia <= 0 or self.hambre <=1:
print ("El gato no quiero jugar")
else:
self.energia -=1
self.hambre -= 2
print ("Al gato le encanta jugar")
def dormir(self, horas):
self.energia += horas
print ("El gato tomo una siesta")
Al hacer esto la clase Gato ya hereda de la clase Felino y con ello hereda las variables y funciones del Felino. Es decir si ejecutamo gato.rugido() ahora el gato dará un rugido.
gato = Gato(3,3)
# Se creo un gato
gato.rugido()
# El felino dio un rugido
Herencia Múltiple
La Herencia múltiple es cuando una clase hereda de varias clases (no solo de una).
En los ejemplos, podemos hacer que la clase Gato herede de Felino y de Mascota:
class Mascota:
def __init__(self):
print("Se creo la mascota")
def sientate(self):
print("La mascota se sentó")
class Felino:
def __init__(self):
print("Ha nacido un felino!")
def rugido(self):
print("El felino dió un rugido.")
class Gato(Felino, Mascota):
def __init__(self, energia, hambre):
self.energia = energia
self.hambre = hambre
print("Un gato ha nacido!")
def miau(self):
print("Miauuu!")
def tomar_leche(self, leche_en_litros):
self.hambre += leche_en_litros
print ("El gato toma su leche")
def acariciar(self):
print ("Prrrrr...")
def jugar(self):
if self.energia <= 0 or self.hambre <=1:
print ("El gato no quiero jugar")
else:
self.energia -=1
self.hambre -= 2
print ("Al gato le encanta jugar")
def dormir(self, horas):
self.energia += horas
print ("El gato tomo una siesta")
Ahora cuando creemos una instancia del gato podremos usar tanto lo que herede de Felino como lo que herede de Mascota.
gato = Gato(3,3)
# Se creo un gato
gato.rugido()
# El felino dio un rugido
gato.sientate()
# La mascota se sentó
Polimorfismo
CitarEl polimorfismo se refiere a la posibilidad de definir múltiples clases con funcionalidad diferente, pero con métodos o propiedades denominados de forma idéntica
o también:
CitarCapacidad que tienen los objetos de una clase de responder al mismo mensaje o evento en función de los parámetros utilizados durante su invocación.
class Gato:
def ruge(self):
print("El gato maulla")
class Perro:
def ruge(self):
print("El perro ladra")
def rugir(animal):
animal.ruge()
gato = Gato()
perro = Perro()
rugir(gato)
# 'El gato maulla'
rugir(perro)
# 'El perro ladra'
Como vemos, ambas clases tiene una función identica, pero en la función rugir() (la que está afuera), nosotros "seleccionamos" el animal (clase) que rugirá.
Encapsulamiento
CitarLo que hace el encapsulamiento es impedir la visualización o acceso de las variables de manera directa. En otros lenguajes esto se logra al momento de declarar la variable como public y private, sin embargo en python es algo distinto. Para declarar una variable o función como privada, el nombre de la función o variable a ser declarado debe comenzar con doble guion abajo. Esto bastará para que lo declarado sea reconocido como privado.
class Ejemplo:
def __init__(self):
print("Hola")
def publica(self):
print("Soy publica!")
def __privada(self):
print("Soy privada!")
e = Ejemplo()
print(e.publica())
print(e.__privada())
Citar
Traceback (most recent call last):
Hola
Soy publica!
None
File "C:\Users\Barlan\Desktop\ejemplos.py", line 13, in <module>
print(e.__privada())
AttributeError: 'Ejemplo' object has no attribute '__privada'
Como vemos, no "encuentra" la función __privada, ya que es privada, no se puede acceder a ella. Solo sirve internamente.
También podemos declarar variables privadas:
class ClaseOtroEjemplo:
def __init__(self):
self.publico = 'variable publica'
self.__privado = 'variable privada'
def obtener_privado(self):
print self.__privado
En __init__ declaramos 2 variables: una pública y una privada.
No se puede acceder a una función privada de manera externa.
Pero en caso necesario, necesitamos una función que devuelva lo que la variable privada contiene.
Entendemos entonces, que
la variable privada es solo de lectura, y no se puede modificar.
En cambio, la pública si puede ser consultada, y modificada.
¿Errores, Críticas, Consejos?
Abajo en los comentarios. xD
Te ha hablado Barlan y te deseo... buenas noches.
Muy bueno , últimamente me estoy documentando sobre POO y esto viene de perlas.
Por cierto , me encantó la despedida del tópico a lo Dross jajajajaja
Wow!! felicidades Barlan, he intentado entender/aprender POO un montón de veces y tengo que decir que contigo es la primera vez que todo me ha quedado super claro, realmente espero que sigas con post de este estilo y sobre todo explicandolos así de bien. :)
excelente ! muchas gracias amigo, me aclaro unas dudas estoy empezando hace poco con el orientado a objeto y tenia unas dudas !!
saludos