Dominando la Programación Orientada a Objetos en Python: Clases, Herencia, Encapsulación y Polimorfismo
Programación Orientada a Objetos en Python
Esta guía recorre los conceptos centrales de la Programación Orientada a Objetos (POO) en Python, con ejemplos prácticos que ilustran cómo construir código robusto y reutilizable.
Video: Programación Orientada a Objetos en Python
Programación Orientada a Objetos
Python es un lenguaje multi-paradigma que soporta varios estilos de programación. Uno de los enfoques más poderosos es modelar problemas usando objetos —un enfoque conocido como Programación Orientada a Objetos (POO).
Un objeto posee dos características esenciales:
- Atributos (datos)
- Comportamiento (métodos)
Por ejemplo, un loro es un objeto con atributos como nombre, edad y color, y comportamientos como cantar() y bailar().
La POO en Python promueve código reutilizable, adhiriéndose al principio DRY (Don't Repeat Yourself - No Te Repitas).
Clase
Una class es un plano que define la estructura y comportamiento de los objetos. Piensa en ella como un boceto detallado de un loro: especifica qué propiedades y acciones puede tener un loro.
class Loro:
pass
Aquí, Loro es una clase vacía. Las instancias de esta clase se crean después.
Objeto
Un objeto (o instancia) es una realización concreta de una clase. Cuando se define una clase, no se asigna memoria; solo existe la plantilla. Instanciar la clase crea el objeto.
obj = Loro()
En el ejemplo siguiente, construimos una clase Loro funcional y creamos dos instancias, azul y woo:
class Loro:
# Atributo de clase
especie = "ave"
# Atributos de instancia
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
# Instanciar la clase
azul = Loro("Azul", 10)
woo = Loro("Woo", 15)
# Acceder a atributos de clase
print("Azul es un {}".format(azul.__class__.especie))
print("Woo también es un {}".format(woo.__class__.especie))
# Acceder a atributos de instancia
print("{} tiene {} años".format(azul.nombre, azul.edad))
print("{} tiene {} años".format(woo.nombre, woo.edad))
Salida
Azul es un ave Woo también es un ave Azul tiene 10 años Woo tiene 15 años
En este snippet, especie es un atributo de clase compartido por todos los loros, mientras que nombre y edad son atributos de instancia únicos para cada objeto.
Métodos
Los métodos son funciones definidas dentro de una clase que describen el comportamiento del objeto. Se invocan sobre instancias de la clase.
class Loro:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def cantar(self, cancion):
return f"{self.nombre} canta {cancion}"
def bailar(self):
return f"{self.nombre} está bailando ahora"
# Instanciar y usar métodos
azul = Loro("Azul", 10)
print(azul.cantar("'Feliz'"))
print(azul.bailar())
Salida
Azul canta 'Feliz' Azul está bailando ahora
Herencia
La herencia permite que una nueva clase herede atributos y métodos de una clase existente, promoviendo reutilización de código y jerarquía lógica.
# Clase base
class Ave:
def __init__(self):
print("Ave lista")
def quienEs(self):
print("Ave")
def nadar(self):
print("Nadar más rápido")
# Clase derivada
class Pinguino(Ave):
def __init__(self):
super().__init__()
print("Pingüino listo")
def quienEs(self):
print("Pingüino")
def correr(self):
print("Correr más rápido")
peggy = Pinguino()
peggy.quienEs()
peggy.nadar()
peggy.correr()
Salida
Ave lista Pingüino listo Pingüino Nadar más rápido Correr más rápido
Encapsulación
La encapsulación restringe el acceso directo al estado interno de un objeto, protegiendo la integridad de los datos. En Python, los atributos privados se denotan con guion bajo inicial (simple o doble).
class Computadora:
def __init__(self):
self.__precio_max = 900
def vender(self):
print(f"Precio de venta: {self.__precio_max}")
def setMaxPrice(self, price):
self.__precio_max = price
c = Computadora()
c.vender()
# Intentar modificar directamente
c.__precio_max = 1000
c.vender()
# Usar método setter
c.setMaxPrice(1000)
c.vender()
Salida
Precio de venta: 900 Precio de venta: 900 Precio de venta: 1000
Polimorfismo
El polimorfismo permite que objetos de diferentes clases sean tratados a través de una interfaz compartida, habilitando código flexible que puede operar sobre varios tipos de objetos.
class Loro:
def volar(self):
print("El loro puede volar")
def nadar(self):
print("El loro no puede nadar")
class Pinguino:
def volar(self):
print("El pingüino no puede volar")
def nadar(self):
print("El pingüino puede nadar")
# Interfaz común
def prueba_vuelo(ave):
ave.volar()
azul = Loro()
peggy = Pinguino()
prueba_vuelo(azul)
prueba_vuelo(peggy)
Salida
El loro puede volar El pingüino no puede volar
Conclusiones Clave
- La POO estructura el código para claridad y mantenibilidad.
- Las clases permiten reutilización de código mediante herencia.
- La encapsulación protege los datos internos.
- El polimorfismo ofrece interfaces flexibles entre tipos de objetos.
python
- Seguimiento Automático de Objetos por Visión Artificial con Raspberry Pi y OpenCV
- Clases y objetos en C#: Fundamentos para POO robusta
- Dominando tipos de datos en Python: Guía práctica
- Dominando operadores en Python: Guía completa
- Dominando Diccionarios en Python: Creación, Manipulación y Técnicas Avanzadas
- Dominando Excepciones Personalizadas en Python: Guía Práctica
- Dominando la Herencia en Python: Conceptos, Sintaxis y Ejemplos Prácticos
- Programación Orientada a Objetos en Python: Guía Completa y Práctica
- Patrón Singleton en Java explicado: Cómo implementarlo y usarlo de forma segura
- Domina Java: Entendiendo Objetos, Clases y Conceptos Básicos de POO
- Serialización de Objetos en Java: Persistencia y Restauración de Objetos