Skip to content

Programación orientada a objetos

josuemontano edited this page Nov 24, 2014 · 6 revisions

Programación orientada a objetos

La programación orientada a objetos (POO) es un paradigma de programación que utiliza la abstracción para crear modelos basados ​​en el mundo real. Utiliza diversas técnicas de paradigmas previamente establecidas, incluyendo la modularidad, polimorfismo y encapsulamiento.

Este paradigma pretende promover una mayor flexibilidad y facilidad de mantenimiento en la programación. Gracias a su fuerte énfasis en la modularidad, el código orientado al objetos está concebido para ser más fácil de desarrollar y más fácil de entender posteriormente, prestándose a un análisis más directo, a una mayor codificación y comprensión de situaciones y procedimientos complejos que otros métodos de programación menos modulares.

La POO puede considerarse como el diseño de software a través de una conjunto de objetos que cooperan, a diferencia de un punto de vista tradicional en el que un programa puede considerarse como un conjunto de funciones, o simplemente como una lista de instrucciones para la computadora. En la programación orientada a objetos, cada objeto es capaz de recibir mensajes, procesar datos y enviar mensajes a otros objetos. Cada objeto puede verse como una pequeña máquina independiente con un papel o responsabilidad definida.

Clases

Define las características del objeto.

Podemos considerar una clase como una colección de objetos que poseen características y operaciones comunes. Una clase contiene toda la información necesaria para crear nuevos objetos, son los modelos sobre los cuáles serán construidos.

En Python definimos una clase con la palabra reservada class.

class NumeroComplejo:
    pass

En el ejemplo supracitado, el nombre de la clase es NumeroComplejo. Aunque no es requerido por el intérprete, los nombres de las clases se escriben por convención capitalizadas. Las clases pueden (y siempre deberían) tener comentarios.

Atributos

Una característica del objeto, como el color.

Los atributos describen el estado de un objeto. Pueden ser de cualquier tipo de dato.

class NumeroComplejo:
    """ Representa un numero complejo """
    real = 0
    imaginario = 0

Métodos

Una apacidad del objeto, como caminar.

Los métodos describen el comportamiento de los objetos de una clase. Representan las operaciones que se pueden realizar con los objetos de la clase. La ejecución de un método puede conducir a cambiar el estado del objeto.

Se definen de la misma forma que las funciones normales pero deben declararse dentro de la clase y su primer argumento siempre referencia a la instancia que lo invoca.

class NumeroComplejo:
    """ Representa un numero complejo """
    real = 0
    imaginario = 0j

    def get_conjugado(self):
        return NumeroComplejo(self.real, -self.imaginario)

Como habrá notado, por convención, el primer argumento de cualquier método se nombra self. self no es una palabra reservada, pero, nuevamente por convención, no utilice esta palabra para nombrar ninguna variable jamás.

Creación de objetos

Las clases por sí mismas, no son más que modelos que nos servirán para crear objetos en concreto. A la acción de crear objetos, se la denomina instanciar una clase. Por su parte, las instancias de una clase se denominan objetos.

En Python instanciamos una clase invocando a un método especial llamado constructor. Este tiene el mismo nombre que la clase y retorna una instancia del tipo de dicha clase.

NumeroComplejo()
type(NumeroComplejo())

Cada llamada al constructor devuelve un objeto distinto. A cada instancia podemos darle un nombre:

a = NumeroComplejo()
b = NumeroComplejo()

objeto = NumeroComplejo()

Una vez creados los objetos, podemos trabajar con ellos. Si queremos que un determinado objeto ejecute un método, utilizamos el operador punto (.). A esto se le conoce como paso de mensajes.

objeto.get_conjugado()

Los objetos se manipulan mediante el paso de mensajes.

También podemos acceder a sus atributos utilizando el operador punto (.).

objeto.real
objeto.imaginario

Constructor

Se llama a __init__ inmediatamente después que se ha creado una instancia de la clase en cuestión mediante una llamada al constructor (el cual no vemos). Por tanto podemos sobreescibir este método para inicializar el valor de cada atributo de la nueva instancia.

class NumeroComplejo:
    """ Representa un numero complejo """
    real = 0
    imaginario = 0j

    def __init__(self, real=0, imaginario=0):
        self.real = real
        self.imaginario = imaginario

    def get_conjugado(self):
        return NumeroComplejo(self.real, -self.imaginario)

a = NumeroComplejo(5.5, 0.9j)
b = NumeroComplejo(imaginario=-0.5j)

Note que el método __init__ nunca retorna un valor.

Herencia

Una clase puede heredar características y comportamiento de otra clase.

La herencia es un mecanismo que permite la definición de una clase a partir de la definición de otra ya existente. La herencia está fuertemente ligada a la reutilización del código en la OOP. Esto es, el código de cualquiera de las clases puede ser utilizado sin más que crear una clase derivada de ella, o bien una subclase.

En Python al definir una sublcase debemos indicar entre paréntesis el nombre de la clase de la cual hereda:

class NumeroReal(NumeroComplejo):
    """ Representa un numero real """
    pass

a = NumeroReal()
type(a)

a.real
a.imaginario
a.get_conjugado()

Podemos redefinir comportamientos heredados así como reutilizar el código de la clase padre (invocando sus métodos con super)

class NumeroReal(NumeroComplejo):
    """ Representa un numero real """
    def __init__(self, real):
        # Llamamos a __init__ de NumeroComplejo
        super(NumeroReal, self).__init__(real, 0j)

    def get_conjugado(self):
        # Sobreescribimos el comportamiento de NumeroComplejo
        return NumeroReal(self.real)