La encapsulación es uno de los pilares fundamentales de la Programación Orientada a Objetos (POO). Este concepto se refiere a la agrupación de datos (atributos) y métodos (funciones) que operan sobre esos datos dentro de una única unidad o clase, y a la restricción del acceso directo a algunos de los componentes de un objeto. Esto se hace para prevenir modificaciones no deseadas y para mantener la integridad de los datos.
Conceptos Clave
- Atributos Privados: Atributos que no pueden ser accedidos directamente desde fuera de la clase.
- Métodos Privados: Métodos que no pueden ser llamados directamente desde fuera de la clase.
- Getters y Setters: Métodos públicos que permiten acceder y modificar los atributos privados de una clase.
- Abstracción: Ocultar los detalles internos y mostrar solo la funcionalidad necesaria.
Ejemplo Práctico
Vamos a crear una clase CuentaBancaria
que encapsula los datos y métodos relacionados con una cuenta bancaria.
Definición de la Clase
class CuentaBancaria: def __init__(self, titular, saldo): self.__titular = titular # Atributo privado self.__saldo = saldo # Atributo privado # Método público para obtener el saldo def obtener_saldo(self): return self.__saldo # Método público para depositar dinero def depositar(self, cantidad): if cantidad > 0: self.__saldo += cantidad print(f"Depósito exitoso. Nuevo saldo: {self.__saldo}") else: print("La cantidad a depositar debe ser positiva.") # Método público para retirar dinero def retirar(self, cantidad): if 0 < cantidad <= self.__saldo: self.__saldo -= cantidad print(f"Retiro exitoso. Nuevo saldo: {self.__saldo}") else: print("Fondos insuficientes o cantidad inválida.") # Método público para obtener el titular def obtener_titular(self): return self.__titular # Método público para cambiar el titular def cambiar_titular(self, nuevo_titular): self.__titular = nuevo_titular print(f"El titular ha sido cambiado a {self.__titular}")
Uso de la Clase
# Crear una instancia de CuentaBancaria cuenta = CuentaBancaria("Juan Pérez", 1000) # Obtener el saldo print(cuenta.obtener_saldo()) # Salida: 1000 # Depositar dinero cuenta.depositar(500) # Salida: Depósito exitoso. Nuevo saldo: 1500 # Retirar dinero cuenta.retirar(200) # Salida: Retiro exitoso. Nuevo saldo: 1300 # Obtener el titular print(cuenta.obtener_titular()) # Salida: Juan Pérez # Cambiar el titular cuenta.cambiar_titular("Ana Gómez") # Salida: El titular ha sido cambiado a Ana Gómez
Ejercicio Práctico
Ejercicio 1
Crea una clase Producto
que encapsule los datos de un producto en una tienda. La clase debe tener los siguientes atributos y métodos:
- Atributos privados:
nombre
,precio
,cantidad
. - Métodos públicos:
obtener_nombre()
: Devuelve el nombre del producto.cambiar_nombre(nuevo_nombre)
: Cambia el nombre del producto.obtener_precio()
: Devuelve el precio del producto.cambiar_precio(nuevo_precio)
: Cambia el precio del producto.obtener_cantidad()
: Devuelve la cantidad disponible del producto.cambiar_cantidad(nueva_cantidad)
: Cambia la cantidad disponible del producto.
Solución
class Producto: def __init__(self, nombre, precio, cantidad): self.__nombre = nombre self.__precio = precio self.__cantidad = cantidad def obtener_nombre(self): return self.__nombre def cambiar_nombre(self, nuevo_nombre): self.__nombre = nuevo_nombre print(f"El nombre del producto ha sido cambiado a {self.__nombre}") def obtener_precio(self): return self.__precio def cambiar_precio(self, nuevo_precio): if nuevo_precio > 0: self.__precio = nuevo_precio print(f"El precio del producto ha sido cambiado a {self.__precio}") else: print("El precio debe ser positivo.") def obtener_cantidad(self): return self.__cantidad def cambiar_cantidad(self, nueva_cantidad): if nueva_cantidad >= 0: self.__cantidad = nueva_cantidad print(f"La cantidad del producto ha sido cambiada a {self.__cantidad}") else: print("La cantidad no puede ser negativa.")
Uso de la Clase Producto
# Crear una instancia de Producto producto = Producto("Laptop", 1500, 10) # Obtener el nombre del producto print(producto.obtener_nombre()) # Salida: Laptop # Cambiar el nombre del producto producto.cambiar_nombre("Laptop Gamer") # Salida: El nombre del producto ha sido cambiado a Laptop Gamer # Obtener el precio del producto print(producto.obtener_precio()) # Salida: 1500 # Cambiar el precio del producto producto.cambiar_precio(1600) # Salida: El precio del producto ha sido cambiado a 1600 # Obtener la cantidad del producto print(producto.obtener_cantidad()) # Salida: 10 # Cambiar la cantidad del producto producto.cambiar_cantidad(15) # Salida: La cantidad del producto ha sido cambiada a 15
Resumen
En esta sección, hemos aprendido sobre la encapsulación, uno de los principios fundamentales de la Programación Orientada a Objetos. Hemos visto cómo los atributos y métodos privados pueden proteger los datos de una clase y cómo los métodos públicos (getters y setters) permiten el acceso controlado a esos datos. La encapsulación ayuda a mantener la integridad de los datos y a prevenir modificaciones no deseadas, lo que resulta en un código más seguro y mantenible.
En el siguiente tema, exploraremos los métodos mágicos, que nos permitirán personalizar el comportamiento de nuestras clases de manera avanzada.
Curso de Programación en Python
Módulo 1: Introducción a Python
- Introducción a Python
- Configuración del Entorno de Desarrollo
- Sintaxis de Python y Tipos de Datos Básicos
- Variables y Constantes
- Entrada y Salida Básica
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for y while
- Herramientas de Control de Flujo
- Comprensiones de Listas
Módulo 3: Funciones y Módulos
- Definición de Funciones
- Argumentos de Función
- Funciones Lambda
- Módulos y Paquetes
- Visión General de la Biblioteca Estándar
Módulo 4: Estructuras de Datos
Módulo 5: Programación Orientada a Objetos
Módulo 6: Manejo de Archivos
- Lectura y Escritura de Archivos
- Trabajo con Archivos CSV
- Manejo de Datos JSON
- Operaciones de Archivos y Directorios
Módulo 7: Manejo de Errores y Excepciones
- Introducción a las Excepciones
- Manejo de Excepciones
- Lanzamiento de Excepciones
- Excepciones Personalizadas
Módulo 8: Temas Avanzados
- Decoradores
- Generadores
- Administradores de Contexto
- Concurrencia: Hilos y Procesos
- Asyncio para Programación Asíncrona
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con unittest
- Desarrollo Guiado por Pruebas
- Técnicas de Depuración
- Uso de pdb para Depuración
Módulo 10: Desarrollo Web con Python
- Introducción al Desarrollo Web
- Fundamentos del Framework Flask
- Construcción de APIs REST con Flask
- Introducción a Django
- Construcción de Aplicaciones Web con Django
Módulo 11: Ciencia de Datos con Python
- Introducción a la Ciencia de Datos
- NumPy para Computación Numérica
- Pandas para Manipulación de Datos
- Matplotlib para Visualización de Datos
- Introducción al Aprendizaje Automático con scikit-learn