Lenguajes de programación

INS240 – Lenguajes de Programación
Ingeniería en Computación e Informática

Programación orientada a objetos con Python

Orientación a Objetos

Conceptos

  • Objeto
  • Clase
  • Mensaje
  • Método
  • Interfaz
  • Herencia

Python: Clases y Objetos

  • Python está completamente orientado a objetos: puede definir sus propias clases, heredar de las que usted defina o de las incorporadas en el lenguaje, e instanciar las clases que haya definido.
  • En Python las clases se definen mediante la palabra reservada class seguida del nombre de la clase, dos puntos (:) y a continuación, indentado, el cuerpo de la clase.

Python: Clases y Objetos

  • En este ejemplo el nombre de la clase es Ejemplo
    y no hereda de otra clase. Por convención las clases empiezan en Mayúscula.
  • Esta clase no define atributos pero no puede estar vacía para eso usamos la función pass, equivalente en otros lenguajes a usar {}
# Ejemplo:
class Ejemplo:
    pass

El método __init__

Las clases de Python no tienen constructores o destructores explícitos.

Las clases de Python tienen algo similar a un constructor: el método __init__.

import math

class Complejo(Object):
    def __init__(self, real, imaginario):
        self.real = real
        self.img = imaginario

    def abs(self):
        print math.sqrt((self.real*self.real)+(self.img*self.img))

El método __init__

  • __init__ se llama inmediatamente tras crear una instancia de la clase.
  • Sería tentador pero incorrecto denominar a esto el constructor de la clase.
  • Es tentador porque parece igual a un constructor (por convención, __init__ es el primer método definido para la clase), actúa como uno (es el primer pedazo de código que se ejecuta en una instancia de la clase recién creada), e incluso suena como uno. 
  • Incorrecto, porque el objeto ya ha sido construido para cuando se llama a __init__, y ya tiene una referencia válida a la nueva instancia de la clase. Pero __init__ es lo más parecido a un constructor que va a encontrar en Python, y cumple el mismo papel.

El método __init__

  • El primer atributo o variable de cada método de clase, incluido __init__, es siempre una referencia a la instancia actual de la clase.
  • Por convención, este argumento siempre se denomina self. En el método __init__, self se refiere al objeto recién creado; en otros métodos de la clase, se refiere a la instancia cuyo método ha sido llamado.
  • Los métodos __init__ pueden tomar cualquier cantidad de argumentos, e igual que las funciones, éstos pueden definirse con valores por defecto, haciéndoles opcionales para quien invoca.

El método __init__

  • Por convención, el primer argumento de cualquier clase de Python (la referencia a la instancia) se denomina self.
  • Cumple el papel de la palabra reservada this en C++ o Java, pero self no es una palabra reservada en Python, sino una mera convención.
  • Aunque necesita especificar self de forma explícita cuando define el método, no se especifica al invocar el método; Python lo añadirá de forma automática.

Instanciación de las
Clases

  • Crear un objeto o instanciar una clase en Python es muy sencillo.
  • Para instanciar una clase, simplemente se invoca a la clase como si fuera una función, pasando los argumentos que defina el método __init__. El valor de retorno será el objeto recién creado.

Instanciación de las
Clases

import math

class Complejo(Object):
    def __init__(self, real, imaginario):
        self.real = real
        self.img = imaginario

    def abs(self):
        print math.sqrt((self.real*self.real)+(self.img*self.img))

def main():
    numero = Complejo(3,4)
    numero.abs()

if __name__ == '__main__':
    main()

Borrar Objetos

  • Crear instancias nuevas es sencillo, destruirlas lo es más.
  • En general, no hay necesidad de liberar de forma explícita las instancias, porque se eliminan automáticamente.
  • Son raras las pérdidas de memoria en Python.

Atributos de datos

  • Python admite atributos de datos (llamados variables de
    instancia en Java, y variables miembro en C++).
  • Para hacer referencia a este atributo desde código que esté fuera de la clase, debe calificarlo con el nombre de la instancia, instancia.data, de la misma manera que calificaría una función con el nombre de su módulo.
  • Para hacer referencia a atributos de datos desde dentro de la clase, use self como calificador.
  • Por convención, todos los atributos de datos se inicializan en el método __init__. Sin embargo, esto no es un requisito, ya que los atributos, al igual que las variables locales, comienzan a existir cuando se les asigna su primer valor.

Atributos de datos

import math

class Complejo(Object):
    def __init__(self, real, imaginario):
        self.real = real
        self.img = imaginario

    def abs(self):
        print math.sqrt((self.real*self.real)+(self.img*self.img))

def main():
    numero = Complejo(3,4)
    numero.abs()

    print numero.real
    print numero.img 
        
if __name__ == '__main__':
    main()

Herencia

  • Una de las principales propiedades de las clases es la herencia. Esta propiedad nos permite crear nuevas clases a partir de clases existentes, conservando las propiedades de la clase original y añadiendo otras nuevas.
  • La nueva clase obtenida se conoce como clase derivada, y las clases a partir de las cuales se deriva, clases base. Además, cada clase derivada puede usarse como clase base para obtener una nueva clase derivada.

 

Herencia

  • Definición de una clase heredada en Python.

 

class Instrumento:
    pass

class Guitarra(Instrumento):
    pass

class Bajo(Instrumento):
    pass

Herencia: El Método __init__

Cuando creamos una clase derivada a partir de una clase padre y tenemos que la clase derivada proporciona o requiere su propio método __init__ , este método de la clase derivada debe llamar explícitamente el método __init__ de la clase base.

 

Herencia:  __init__


class Animal:
    def __init__(self):
        print "Animal creado"

    def quien_soy(self):
        print "Animal"

    def comer(self):
        print "Estoy comiendo"

class Perro(Animal):
    def __init__(self):
        Animal.__init__(self)
        print "Perro creado"

    def quien_soy(self):
        print "perro"

    def ladrar(self):
        print "woof woof<!"

Ejercicio 1

Diseñar un programa que modele acciones y atributos de un perrro. El programa debe permitir realizar las acciones de caminar, comer, ladrar y que tenga la posibilidad de enfermarse. Al crear un objeto perro debe comenzar con 1000 unidades de energía.

Las reglas para implementar estas acciones son las siguientes:

  • Cada vez que se alimenta al perro este se debe acumular 300 unidades de energía
  • Cada vez que el perro camine se debe restar 200 unidades de energía
  • Cada vez que el perro se enferme debe restar unidades de energía de forma aleatoria

Ejercicio 1: Solución

import random


class Perro():

    def __init__(self, nombre, edad, energia):
        self.nombre = nombre
        self.edad = edad
        self.energia = energia


    def caminar(self):

        if self.energia < 0:
            print(self.nombre, "Esta muerto :C", "no puede caminar")
        else:
            self.energia = self.energia - 200
            print(self.nombre, "Esta caminando, energia actual =", self.energia)

    def comer(self):

        if self.energia < 0:
            print(self.nombre, "Esta muerto :C", "no puede comer")
        else:
            self.energia = self.energia + 300
            print(self.nombre, "Esta comiendo, energia actual =", self.energia)



    def ladrar(self):

        if self.energia < 0:
            print(self.nombre, "Esta muerto :C", "no puede ladrar")
        else:
            self.energia = self.energia - 100
            print(self.nombre, "Esta ladrando, energia actual =", self.energia)


    def enfermarse(self):

        if self.energia < 0:
            print(self.nombre, "Esta muerto :C", "no puede enfermarse")
        else:
            self.energia = self.energia - random.randint(1, self.energia)
            print(self.nombre, "Esta enfermo, energia actual =", self.energia)


    def __str__(self):
        return self.nombre

Guía de Ejercicios

Made with Slides.com