martes, 1 de septiembre de 2015

Practica No.4 Programación Orientada a Objetos en Python

Conceptos Generales

La programación orientada a objetos (POO) es un paradigma de programación en el que los conceptos del mundo real relevantes para nuestro problema se modelan a través de clases y objetos, y nuestro programa consiste en una serie de interacciones entre estos objetos.

Los objetos se crean a partir de las clases, y pueden interactuar entre sí mediante mensajes. Algunos de los lenguajes que permiten la programación orientada a objetos son: Smalltalk, C++, Objective-C, C#, Java, Javascript, Python, entre otros.

El concepto básico para entender el funcionamiento de la POO son los conceptos de Clase y Objetos, los cuales podemos definirlos brevemente de la siguiente manera:

Las clases permiten agrupar en un nuevo tipo los datos y las funcionalidades asociadas a dichos datos, favoreciendo la separación entre los detalles de la implementación de las propiedades esenciales para su uso. Una clase define propiedades y comportamiento que se muestran en los entes llamados objetos (o instancias de una clase). La clase actúa como molde de un conjunto de objetos, de los que se dice que pertenecen a la clase.

En términos más abstractos, podemos pensar en las clases como definiciones y en los objetos como expresiones concretas de dichas definiciones.

Implementación en Python.

Antes que nada veamos el siguiente ejemplo
class Gato:
    def __init__(self, energia, hambre):
        self.energia = energia
        self.hambre = hambre
        print ('Se creo un gato')
 
    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')


gato = Gato(5, 5)
gato.acariciar()
gato.jugar()
gato.jugar()
gato.jugar()
print (gato.energia)
print (gato.hambre)
gato.tomar_leche(4) 
print (gato.hambre)
gato.jugar()
print (gato.hambre)
print (gato.energia)

Como podemos ver creamos una clase a la que llamamos Gato con sus métodos y atributos propios, hay que fijarnos primero en la función _init_, como podemos observar este es el método que funciona como constructor del método y es el primero que se ejecuta al instanciar un objeto.

Aquí otra cosa a resaltar es que todos los métodos de la clase deben recibir como parámetro el atributo self, aunque nosotros al llamar a la función no lo indicamos, esto es para que cada método pueda acceder a los atributos y métodos propios de la clase. Para instanciar un objeto lo hacemos usando de la instrucción siguiente:
gato = Gato(5, 5)
Es importante pasar los parámetros que solicita la función _init_ al momento de realizar la instancia, y una vez que se realiza correctamente, ya podemos hacer referencia a los métodos y atributos de la clase usando el operador “.”.

Otro concepto importante es la herencia es decir generar una clase nueva a partir de otra, de la que recibe su comportamiento y estado (métodos y atributos), adaptándolos o ampliándolos según sea necesario. En el siguiente ejemplo vemos la clase Felino y la clase Gato que hereda de ella, esto se hace desde la declaración de la clase Gato como vemos en la siguiente sección de código:
class Felino:
    def __init__(self):
        print ('se creo el felino')
 
    def rugido(self):
        print ('El felino dio un rugido')
 
class Gato(Felino):
    def __init__(self, energia, hambre):
        self.energia = energia
        self.hambre = hambre
        print ('Se creo un gato')
 
    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')

gato = Gato(3,3) 
gato.rugido()
De este modo el método rugido que se definió en la clase Felino puede ser accedido desde la clase Gato.

Algo que no existe en otros lenguajes de programación es el de poder heredar de múltiples clases al mismo tiempo, sin embargo esto si existe en Python, y el siguiente ejemplo es una muestra de ello, ya que nuestra clase Gato hereda tanto de la clase Felino como de la clase Mascota, por lo que puede acceder a métodos de ambas clases:
class Mascota:
    def __init__(self):
        print ('se creo la mascota')
 
    def sientate(self):
        print ('La mascota se sentó')
 
class Felino:
    def __init__(self):
        print ('se creo el felino')
 
    def rugido(self):
        print ('El felino dio un rugido')
 
class Gato(Felino, Mascota):
    def __init__(self, energia, hambre):
        self.energia = energia
        self.hambre = hambre
        print ('Se creo un gato')
 
    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')

gato = Gato(3,3)
gato.rugido() 
gato.sientate()
Es importante también repasar el concepto de polimorfimo, es decir el poder realizar algo de muchas maneras diferentes o bien, poder responder a la misma función de varias maneras, en el ejemplo siguiente utilizamos una sola función para acceder a dos funciones distintas en diferentes clases.
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)
rugir(perro)

El último concepto que vamos a tratar en este post es sobre el encapsulamiento de los métodos y variables, esto se refiere a impedir la visualización o acceso de las variables de manera directa. 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.

El siguiente ejemplo muestra cómo utilizar el encapsulamiento en métodos y variables.
class Encapsulamiento:
   def __init__(self):
       self.publico = 'variable publica'
       self.__privado = 'variable privada'
 
   def obtener_privado(self):
       print (self.__privado)

Ejemplo = Encapsulamiento()
print (Ejemplo.publico)
#print (Ejemplo.__privado)  Error
Ejemplo.obtener_privado()
Todos los ejemplos fueron tomados del siguiente link. Puede descargarlos desde el siguiente link

No hay comentarios.:

Publicar un comentario