Introducción a la programación orientada a objetos
Índice
Introducción
Este es otro paradigma distinto a los que ya conocemos que son: el funcional y el imperativo.
Un objeto se usa creando clases.
Las clases son los elementos fundamentales de la POO (Programación orientada a objetos).
Una clase describe al objeto.
Imaginemos que queremos describir a un perro.
Podemos pensar que tiene alguna características como, raza, color, peso y nombre, seguramente tendrá varias mas, pero de momento trabajemos con esto.
En Python las clases se declaran mediante el uso de la palabra reservada class
|
|
En el código anterior hemos declarado una clase Perro, pero de momento no hace nada.
En Python se acostumbra a que el nombre de la clase comience con una letra mayúscula.
Dijimos entonces que nuestro perro tiene ciertos atributos, raza, color peso y nombre, para introducirlos dentro de nuestra clase podemos hacer lo siguiente.
|
|
El nombre de mi perro es " Garabo "
Antes de continuar vamos a establecer ciertas reglas de nombres.
- Si una clase contiene una función la llamamos método.
- Si una clase contiene una variable la llamamos atributo.
Bien, tomando como referencia el código anterior lo primero que observamos es un método(una función) que se llama _init_ este método es conocido como **Constructor**
La declaración de un constructor NO ES obligatoria, es opcional. Sirve, particularmente, para inicializar atributos en el objeto.
|
|
Este método se invoca al momento de crear (instanciar) un objeto.
En Python, todos los métodos de una clase deben tener self como primer parámetro.
En la línea
|
|
Lo que estamos haciendo es crear un objeto de la clase perro y le enviamos los argumentos necesarios que son los que fueron definidos en el método _init_, ellos son raza, color, peso y nombre.
Nótese que el primer argumento self no necesita ser explícitamente enviado.
Esos argumentos, se asignan dentro de los atributos de la clase como indica el siguiente fragmento de código:
|
|
Es decir que:
- “Cocker” se guardó en self.raza
- “Marrón” se guardó en self.color
- 12 se guardó en self.peso
- “Garabo” se guardó en self.nombre
Finalmente cuando hacemos:
|
|
Estamos mostrando el valor asignado en el atributo self.nombre del objeto que creamos, en este ejemplo el atributo self.nombre del objeto en cuestión esta cargado con el valor “Garabo”.
Métodos
Las clases pueden tener métodos (funciones) acorde a las necesidades de las mismas.
Estos métodos son idénticos a los que venimos trabajando a lo largo del taller.
Por ejemplo la clase Perro puede tener un método que muestre el nombre del perro.
|
|
Me llamo Garabo
Me llamo Bufa
Nótese como podemos crear diversos objetos del tipo Perro con solo hacer:
|
|
Recuerden que para acceder a un método hacemos
|
|
Atributos
Las clases, como vimos pueden tener atributos, que se inicializan al momento de instanciar el objeto
|
|
Además, puede tener atributos definidos por defecto.
En el caso de los perros tienen, como atributo definido por defecto, cero manchas.
Entonces podemos hacer lo siguiente:
|
|
0
12
Funciones para poner y devolver datos.
Suele ser una buena idea pensar en los métodos de dos maneras posibles. Algunos métodos devuelven resultados o datos y otros asignan.
Veamos un ejemplo en nuestra clase perro. Supongamos que no queremos, al momento de instanciar el objeto, enviarle argumento alguno, pero si queremos tener la posibilidad de ir poniendo valor a “mano”.
|
|
Garabo
¿Qué es self ?
Si han estado observado detalladamente notarán el uso de la palabra reservada self en varias ocasiones.
Pensemos en lo siguiente.
|
|
Pirulo
La pregunta es:
¿Como sabe el programa distinguir el parámetro nombre de la función init, del atributo nombre definido en la clase Perro?
Muy simple, mediante el uso de self.
Cuando vemos self.atributo nos referimos al atributo de clase y NO al argumento del método.
En esta línea
|
|
self.nombre es el atributo definido adentro de la clase y nombre es simplemente el argumento que enviamos, en este caso “Pirulo”.
Es decir que el valor “Pirulo” se guardará en el atributo “nombre” (definido en la segunda línea del código) del objeto que hemos creado.
Herencia
La herencia es un mecanismo que nos facilita compartir información entre distintas clases.
Por ejemplo, los animales comparten ciertos atributos, color, peso, nombre. Pero también tienen diferencias, el gato maúlla y el perro ladra por ejemplo.
Esto se puede expresar creando una clase madre donde se definen “las cosas que comparten” y clases hijas en donde se definen las diferencias. Todas las clases hijas tomarán (heredan) de la madre todos lo que se encuentre definido en ella.
Veamos un ejemplo para que quede mas claro:
|
|
Guau!
Miau
Luna
Garabo
Podemos pensarlo “como si” el contenido de la clase Animales se hubiera “copiado” dentro de la clase Perro y dentro de la clase Gato
Herencia indirecta
La herencia también puede ser indirecta como se ilustra en el siguiente ejemplo:
|
|
Soy la Segunda
Soy la Primera
Soy la madre
Palabra reservada super
La palabra reservada super() sirve para referirnos al método definido en la clase madre. Por ejemplo:
|
|
Soy la clase Primera
Soy la clase base
Explicación del ciclo de vida de un objeto.
A grandes rasgos podemos decir que el ciclo de vida de un objeto consta de tres etapas:
La creación, la manipulación y la destrucción del objeto.
Habitualmente la primer actividad que hacer hacemos al escribir código en base a este paradigma (POO) es definir la clase a la cual el objeto pertenece.
Luego instanciamos el objeto.
|
|
En este momento se invoca a la función _init_ y se aloca (se reserva) memoria para esta instancia. Después de esto el objeto esta listo para ser usado.
Cuando destruimos un objeto, la memoria alocada se libera.
Ahora bien, un objeto se destruye completamente, cuando el “conteo de referencia” llega a cero, pero ¿Que es el conteo de referencia?
Es el numero de variables y objetos a los que ese elemento se refiere.
A modo de ejemplo
|
|
Es decir, mientras más objetos o variables asociados a num tengamos a lo largo del programa, más referencias tenemos, el operador “de"l borra la referencia, cuando ese conteo de referencias este en 0, se considera (automáticamente) que esa memoria no se necesita mas y por lo tanto, el “Recolector de basura” de Python liberará completamente la memoria.
Este tema tiene mayor profundidad, pero la idea del taller es darle una mínima introducción a este tema que se relaciona con el manejo de la memoria en Python.
Encapsulamiento
El encapsulamiento es una característica que suelen tener los lenguajes orientados a objetos. Se basa en un concepto conocido como ocultamiento de datos el cual establece que los detalles de la implementación de una clase deben estar ocultos para aquellos que hagan uso de la clase en cuestión. En lenguajes de programación, como C++, hacemos uso de ciertas palabras reservadas como public o private para determinar que elementos están ocultos y cuales no.
En Python este acercamiento se hace desde otro punto de vista, la filosofía del lenguaje establece que “somos todos adultos” por lo tanto no tiene sentido poner restricciones de acceso a las clases, en consecuencia, no hay maneras de forzar que un método o atributo sea estrictamente privado.
Sin embargo, hay una pequeña manera de denegar el acceso a métodos y atributos y consiste en escribir __ (dos guiones bajos) delante del nombre del atributo.
|
|
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-c664b4ef8e15> in <module>
3
4 miObjeto = Unaclase()
----> 5 print(miObjeto.__atributo_privado)
AttributeError: 'Unaclase' object has no attribute '__atributo_privado'
De todas formas, este tipo de implementación en Python no es recomendable.
Hasta aquí llegará nuestro taller. Si bien han quedado algunos temas afuera entiendo que se han brindado las herramientas fundamentales para comenzar a construir programas Python. A partir de esto punto pueden seguir investigando y aprendiendo sobre el lenguaje, hay diversidad de temas para conocer:
-
Frameworks que permiten hacer web dinámicas Flask y Django o estáticas Pelican/Lekor/Nikola
-
Herramientas para crear interfaces gráficas Qt, Pysdl, tkinter
-
Módulos interesantes para trabajar la web beatifull soup o para análisis de datos/computación científica pandas/numpy
-
Para hacer juegos pygame o desarrollo para Android kivy.
En fin, tienen infinidad de opciones para seguir investigando y desarrollándose. Espero que el taller les haya sido de utilidad y si me ven en algún espacio de los que suelo trabajar (Universidades o Empresas) no duden en saludarme. Les dejo mi correo electrónico para cualquier consulta que tengan.
victorsaturno@disroot.org
Sin más me despido de ustedes y que tengan éxitos en los caminos que emprendan.