# T.1.2.3 Programación orientada a objetos en Python Como en todos los aspectos de la programación (codigo secuencial, condicional, repetitivo, etc.) es necesario aprender los conceptos de la programación orientada a objetos lo mismo que permita utilizarla de manera efectiva. En este taller se decriben ejemplos muy básicos de la programación orientado objeto. ## Todo es un objeto Como se ha descrito el lenguaje de programación Python todo es manejado como un objeto. Copie el siguiente código en nuevo archivo denominado `pooEjemplo1.py` y luego analice su resultado. A continuación un ejemplo del mismo. ```Python= cosa = list() cosa.append('B-datos') cosa.append('A-datos') cosa.sort() print (cosa) print (cosa[0]) print (cosa.__getitem__(0)) ##tradición verbosa. ``` El resultado se muestra a continuación ``` ['A-datos', 'B-datos'] A-datos A-datos ``` Ahora en la consola de Python digite lo siguiente función: ```powershell In [1]: dir(cosa) ``` Las salida respectiva muestra las capacidades del objeto cosa y es notable que hereda propiedades y métodos del objeto prinicipal list(). ```powershell Out[37]: ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] ``` ## Clase vehículo A continuación se muestra la clase vehículo en donde se específica cada uno de los componentes descritos en clase como son: constructor, métodos, atributos de instancia y atributos de clases. Proceda a crear un nuevo programa y copie el código siguiente y guarde con el nombre `pooClaseVehiculo.py`. ```Python= class Vehiculo: ruedas=4 def __init__(self, color, aceleracion): self.color=color self.aceleracion=aceleracion self.velocidad = 0 def acelera(self): self.velocidad=self.velocidad+self.aceleracion def frena(self): v = self.velocidad= self.aceleracion if v < 0: v=0 self.velocidad=v ``` Una vez guardado el programa anterior proceda a crear un nuevo programa y escriba un nombre al archivo como por ejemplo: `pooEjemplo2.py` y copie el código siguiente. ```Python= #primer formato: import file.py import pooClaseVehiculo c1 = pooClaseVehiculo.Vehiculo('rojo', 20) c2 = pooClaseVehiculo.Vehiculo('amarillo', 30) print(c1.color) print(c2.color) # Segundo formato: from file.py import clase from pooClaseVehiculo import Vehiculo c1 = Vehiculo('verde', 30) c2 = Vehiculo('azul', 40) print(c1.color) print(c2.color) # Tercer formato: from file.py import clase as alias from pooClaseVehiculo import Vehiculo as v c1 = v('negro', 40) c2 = v('blanco', 50) print(c1.color) print(c2.color) ``` Ejecute el código y verifique que la salida sea similar a la siguiente: ```powershell In [3]: runfile('F:/MasterIoT/BasicPython/pooEjemplo2.py', wdir='F:/MasterIoT/BasicPython') Reloaded modules: pooClaseVehiculo rojo amarillo verde azul negro blanco ``` Como pudo notar existen diferentes mecanimos para instanciar la clase previamente definida. En cualquiera de los tres formatos los resultados serán de acuerdo a lo declarado en cada instancia. ## Atributos de clase y de instancia En una clase existen dos tipos diferentes de atributos de datos: atributos de clase y atributos de instancia. * Los atributos de clases son variables compartidas por todas las instancias de esa clase. * Los atributos de instancia, se diferencia de los anteriores porqué son únicos para cada uno de los objetos que pertenecen a dicha clase. En el ejemplo de la clase "Vehiculo", ruedas se ha definido como un atributo de clase, mientras que color, aceleracion y velocidad son atributos de instancia. Para referenciar a un atributo de clase se utiliza, generalmente, el nombre de la clase. Al modificar un atributo de este tipo, los cambios se verán reflejados en todas y cada una las instancias. Copie el siguiente código y cree un nuevo programa dicho programa puede ser `pooEjemplo3.py`. ```Python= from pooClaseVehiculo import vehiculo as v c1 = v('negro', 15) c2 = v('blanco', 15) print(c1.color) print(c2.color) print('El atributo de la clase c1 es: ', c1.ruedas) print('El atributo de la clase c2 es: ', c2.ruedas) print('--------------------------------------------') v.ruedas=2 print('El atributo de la clase c1 es: ', c1.ruedas) print('El atributo de la clase c2 es: ', c2.ruedas) print('--------------------------------------------') c2.ruedas=3 print('El atributo de la clase c1 es: ', c1.ruedas) print('El atributo de la clase c2 es: ', c2.ruedas) ``` Los resultados obtenidos se puede evidenciar en la salida siguiente: ```powershell In [4] runfile('F:/MasterIoT/BasicPython/pooEjemplo3.py', wdir='F:/MasterIoT/BasicPython') Reloaded modules: pooClaseVehiculo negro blanco El atributo de la clase c1 es: 4 El atributo de la clase c2 es: 4 -------------------------------------------- El atributo de la clase c1 es: 2 El atributo de la clase c2 es: 2 -------------------------------------------- El atributo de la clase c1 es: 2 El atributo de la clase c2 es: 3 ``` El resultado muestra qué la instancia vehículo ha tomado los siguientes comportamientos: * En la primera parte ambas instancias el atributo rueda es de 4. * Luego se realiza un cambio y ambas toman un valor 2. * Finalmente, la instancia número c2 su atributo de instancia ha sido cambiado por 3 para las ruedas. ## Herencia en Python La herencia es la capacidad de reutilizar una clase extendiendo sus funcionalidad, por lo qué se puede crear una clase a partir de los métodos y propiedades de una clase padre. Además, se puede agregar nuevos métodos o redefinir los ya existentes, y crear nuevos atributos. A continuación, proceda a crear una nueva clase, esta clase hereda las características y funcionalidades de la clase vehículo. La clase nueva a crear la vamos a llamar `pooClaseVehiculoVolador.py` , y luego copie el siguiente código: ```Python= from pooClaseVehiculo import Vehiculo class VehiculoVolador(Vehiculo): ruedas = 6 def __init__(self, color, aceleracion, esta_volando=False): super().__init__(color, aceleracion) self.esta_volando = esta_volando def vuela(self): self.esta_volando = True def aterriza(self): self.esta_volando = False ``` Como se puede apreciar en la línea número 3 la clase nueva recibe la clase vehículo lo que significa que va a tomar la funcionalidad de dicha clase. En la línea número 6 al invocar la palabra reservada `super()`. Esta función devuelve un objeto temporal de la superclase que permite invocar a los métodos definidos en la misma. Lo que está ocurriendo es que se está redefiniendo el método __init__() de la clase hija usando la funcionalidad del método de la clase padre. Como la clase `vehiculo` es la que define los atributos color y aceleracion, estos se pasan al constructor de la clase padre y, a continuación, se crea el atributo de instancia `esta_volando` solo para objetos de la clase `VehículoVolador`. A continuación un ejemplo en donde al utilizar la herencia, los atributos y métodos de la clase padre también pueden ser referenciados por objetos de la clase hija. Por lo contrario, la clase hija al padre no tendría igual comportamiento. Copie el código y cree un nuevo archivo cuyo nombre puede ser `pooEjemplo4.py`. ```Python= from pooClaseVehiculoVolador import VehiculoVolador as vVolador c1 = vVolador('rojo', 30) print("El tipo de vehículo es un Hexacoptero porque tiene = " , c1.ruedas) c1.vuela() print("El Hexacoptero se encuentra volando = " , c1.esta_volando) c1.acelera() #Por herencia accede al método aceleración print("El Hexacoptero se encuentra acelerando con una velocidad de: " , c1.velocidad) c1.frena() #Por herencia accede al método de franado "frena()" print("El Hexacoptero ha frenado y su velocidad es = " , c1.velocidad) c1.aterriza() print("El Hexacoptero se encuentra volando = " , c1.esta_volando) ``` El resultado se muestra acontinuación: ```powershell In [4] = El tipo de vehículo es un Hexacoptero porque tiene = 6 El Hexacoptero se encuentra volando = True El Hexacoptero se encuentra acelerando con una velocidad de: 30 El Hexacoptero ha frenado y su velocidad es = 0 El Hexacoptero se encuentra volando = False ``` :::info :bulb: **Tarea**: Se le solicita que realice dos clases: 1. La primera clase con nombre **Sensors** dicha clase tendrá los métodos que devuelven: temperatura, humedad, y la fecha-hora del sistema. La idea general es que el valor devuelto de temperatura y humedad sean valores randomicos. 1. La segunda clase herera los métodos de la clase **Sensors** y agrega los métodos de latitud y longitud. Esta última clase se la puede llamar **SensorGPS**. ::: ---- ```Python= ``` ```powershell In [4] ```