Programar con objetos puede parecer complejo al principio, pero entender sus pilares fundamentales te facilitará mucho la tarea. Vamos a ver cómo aplicar abstracción, encapsulamiento, herencia y polimorfismo en un código sencillo.
¿Qué es la abstracción en programación orientada a objetos?
La abstracción te permite definir estructuras básicas sin entrar en detalles específicos. En el código, hemos creado instancias de diferentes vehículos, como un auto, una bicicleta y un camión, asignándoles atributos como marca, modelo y precio. Este enfoque nos permite trabajar con conceptos generales antes de precisar características específicas.
¿Cómo se aplica el encapsulamiento?
El encapsulamiento se refiere a mantener los datos privados dentro de una clase y acceder a ellos solo mediante métodos públicos. En nuestro ejemplo, las variables de instancia de los vehículos son privadas. Solo podemos acceder a ellas a través de métodos específicos, como GetPrice o verificarDisponibilidad, asegurando así que los datos se manejen de manera controlada y segura.
¿Qué rol juega la herencia?
La herencia permite que una clase hija adopte atributos y métodos de una clase padre. Aquí, la clase auto hereda de la clase vehículo, lo que significa que todas las características y comportamientos definidos en vehículo están disponibles en auto sin necesidad de duplicar el código. Este principio facilita la reutilización y extensión del código.
¿Qué es el polimorfismo y cómo se usa?
El polimorfismo permite que diferentes clases respondan a los mismos métodos de maneras distintas. En nuestro caso, tanto el auto como la bicicleta heredan métodos de vehículo, pero cada uno los implementa de forma diferente. Por ejemplo, el método para indicar que el auto está en marcha difiere del método de la bicicleta, que no usa motor. Este comportamiento flexible es clave para escribir código más dinámico y reutilizable.
Permite centrarse en las características esenciales de un objeto.
Ejemplo: Una interfaz "Vehículo" con método "mover", sin especificar cómo se implementa.
Herencia:* Permite que una clase (hija) herede propiedades y métodos de otra (padre).
Promueve la reutilización de código y la jerarquía de clases.
Ejemplo: "Coche" y "Moto" heredan de "Vehículo".
Polimorfismo:* Permite que objetos de diferentes clases respondan al mismo método de manera única.
Facilita el uso de una interfaz común para tipos de datos diversos.
Ejemplo: Diferentes tipos de "Vehículo" implementan el método "mover" de forma distinta.
Buen resumen!
Such nice summary dude, that is the right and value actitud
Quisiera felicitar a la profesora por la excelente manera en que abordó el curso, explicando los conceptos de manera magistral. No obstante, los términos de abstracción y polimorfismo no fueron definidos con precisión. La abstracción puede aplicarse tanto a nivel de clases como de métodos. Las clases que heredan de clases abstractas o que contienen métodos abstractos están obligadas a implementar estos métodos, funcionando como un contrato de desarrollo entre equipos de programación. Además, el polimorfismo se apoya en la abstracción para referenciar los métodos implementados en las clases derivadas. Por último, considero que faltó un mayor detalle en la explicación de la sobreescritura de métodos.
Buen curso
El polimorfismo no solo aplica cuando hay clases abstractas; incluso, el polimorfismo es un concepto que aplica fuera de la programación orientada a objetos, como en programación funcional por ejemplo. Uno de los tipos de polimorfismo explicado en la case es por sobrecarga, pero no es el único; por ejemple este se puede implementar en C y el lenguaje que no tiene objetos, clases abstractas, herencias ni interfaces, y sigue siendo polimorfismo.
Por eso, la definición de la profe es 100% precisa.
Carli me parece brillante, de verdad se nota que sabe muchisimo y la admiro por su conocimiento, pero siento que desde hace 3 clases estoy perdida de como emplear ciertas cosas.
Es que POO es muy avanzado, y este curso es básico.
Hola, Ale
Espero que no te desanimes. La POO es complejo, me llevó mucho tiempo entender y tuve que ver muchas veces las clases y hacer ejercicios en los que muchas veces copié el texto, poco a poco fue tomando forma la idea. No es que la domine por completo, solo ya entiendo lo que sucede.
No te desanimes :-)
Resumen
Abstracción: Simplificación de un sistema complejo mediante la modelación de clases adecuadas.
Encapsulamiento: Ocultación de los detalles internos y exposición de una interfaz pública.
Herencia: Creación de nuevas clases basadas en clases existentes, heredando sus atributos y métodos.
Polimorfismo: Capacidad de tratar diferentes clases como instancias de una misma clase base a través de una interfaz común.
Muchas gracias
Esto me ayudo a aclarar dudas respecto al polimorfismo, ya que era el pilar mas abstracto para mi. :D
Ventajas del Polimorfismo:
Abstracción y Estructuración del Código``:
El polimorfismo permite definir una interfaz común para diferentes clases, lo que facilita la abstracción y la estructuración del código.
Las clases pueden compartir una interfaz común (como un método) sin preocuparse por los detalles de implementación.
Flexibilidad y Extensibilidad``:
El polimorfismo permite agregar nuevas clases o subclases sin afectar el código existente.
Puedes introducir nuevas funcionalidades sin cambiar el código que utiliza la interfaz común.
Legibilidad y Mantenibilidad``:
El uso de polimorfismo hace que el código sea más legible y fácil de mantener.
Las clases que comparten una interfaz común son más intuitivas y coherentes.
Desventajas del Polimorfismo:
Overhead de Rendimiento``:
En algunos casos, el polimorfismo puede tener un pequeño impacto en el rendimiento debido a la resolución dinámica de métodos.
Sin embargo, en la mayoría de las aplicaciones, este impacto es insignificante y no debe ser una preocupación.
Complejidad Adicional``:
El polimorfismo puede aumentar la complejidad del código, especialmente cuando se utilizan jerarquías de clases extensas.
Es importante diseñar cuidadosamente las relaciones entre clases y métodos para evitar confusiones.
Comparación con el Uso de un Diccionario:
Polimorfismo``:
Proporciona una estructura más natural y orientada a objetos.
Permite que las clases compartan una interfaz común y tengan implementaciones específicas.
Es más adecuado cuando las clases tienen comportamientos más complejos y no se pueden reducir a simples pares clave-valor.
Diccionario``:
Es útil cuando necesitas una asignación directa entre claves y valores.
Puede ser más eficiente en términos de acceso a datos (búsqueda por clave).
Es menos flexible en términos de comportamiento y no permite la herencia o la abstracción.
En resumen, el polimorfismo es una herramienta poderosa para diseñar sistemas más flexibles y mantenibles. Siempre debes elegir la opción que mejor se adapte a tus necesidades específicas y al diseño general de tu aplicación.
Excelente!
#Excelente clase! Super dinámica.#Ejercicio FinalizadoclassVehicle:def__init__(self,brand,model,price):#Encapsulación self.brand = brand
self.model = model
self.price = price
self.is_available =Truedefsell(self):if self.is_available: self.is_available =Falseprint(f"El vehiculo {self.brand}. Ha sido vendido.")else:print(f"El vehiculo {self.brand}. No está vendido.")#Abstraccióndefcheck_available(self):return self.is_available
#Abstraccióndefget_price(self):return self.price
defstart_engine(self):raise NotImplementedError("Este método debe ser implementado por la subclase")defstop_engine(self):raise NotImplementedError("Este método debe ser implementado por la subclase")#Herencia classCar(Vehicle):#Polimorfismo defstart_engine(self):ifnot self.is_available:returnf"El motor del coche {self.brand} está en marcha."else:returnf"El coche {self.brand} no está disponible."#Polimorfismo defstop_engine(self):ifnot self.is_available:returnf"El motor del coche {self.brand} se ha detenido."else:returnf"El coche {self.brand} no está disponible."classBike(Vehicle):defstart_engine(self):ifnot self.is_available:returnf"La bicicleta {self.brand} está en marcha."else:returnf"La bicicleta {self.brand} no está disponible."defstop_engine(self):ifnot self.is_available:returnf"La bicicleta {self.brand} se ha detenido."else:returnf"La bicicleta {self.brand} no está disponible."classTruck(Vehicle):defstart_engine(self):ifnot self.is_available:returnf"El motor del camión {self.brand} está en marcha."else:returnf"El camión {self.brand} no está disponible."defstop_engine(self):ifnot self.is_available:returnf"El motor del camión {self.brand} se ha detenido."else:returnf"El camión {self.brand} no está disponible."classCustomer:def__init__(self,name): self.name = name
self.purchased_vehicles =[]defbuy_vehicle(self, vehicle: Vehicle):if vehicle.check_available(): vehicle.sell() self.purchased_vehicles.append(vehicle)else:print(f"Lo siento, {vehicle.brand} no está disponible.")definquire_vehicle(self, vehicle: Vehicle):if vehicle.check_available(): availablity ="Disponible"else: availablity ="No disponible"print(f"El {vehicle.brand} está {availablity} y cuesta {vehicle.get_price()}.")classDealership:def__init__(self): self.inventory =[] self.customers =[]defadd_vehicles(self, vehicle: Vehicle): self.inventory.append(vehicle)print(f"El {vehicle.brand} ha sido añadido al inventario.")defregister_customers(self, customer: Customer): self.customers.append(customer)print(f"El cliente {customer.name} ha sido añadido.")defshow_available_vehicle(self):print("Vehiculos disponibles en la tienda")for vehicle in self.inventory:if vehicle.check_available():print(f" - {vehicle.brand} por {vehicle.get_price()}.")car1 = Car("Toyota","Corolla",20000)bike1 = Bike("Yamaha","MT-07",7000)truck1 = Truck("Volvo","FH16",80000)customer1 = Customer("Carlos")dealership = Dealership()dealership.add_vehicles(car1)dealership.add_vehicles(bike1)dealership.add_vehicles(truck1)#Mostrar vehiculos disponiblesdealership.show_available_vehicle()#Cliente consultar un vehiculocustomer1.inquire_vehicle(car1)#Cliente comprar un vehiculocustomer1.buy_vehicle(car1)#Mostrar vehiculos disponiblesdealership.show_available_vehicle()
👌🏼 Aplico muy bien el polimorfismo, porque la Bicicleta se convirtio en Motocicleta 🏍️ 😅
Los cuatro pilares de la Programación Orientada a Objetos (POO) son los principios fundamentales que guían este paradigma de programación. Son esenciales para entender cómo organizar y estructurar programas de manera más eficiente y modular.
La abstracción consiste en representar los elementos más importantes de un objeto y ocultar los detalles innecesarios
El encapsulamiento es el principio de restringir el acceso directo a los datos de un objeto y permitir interactuar con ellos a través de métodos controlados.
La herencia permite crear nuevas clases basadas en clases existentes, heredando sus atributos y métodos. Esto promueve la reutilización de código y hace más fácil extender las funcionalidades sin necesidad de reescribir todo desde cero
El polimorfismo es la capacidad de que un mismo método pueda tener diferentes comportamientos según el contexto
Siento que los pilares son bastante importantes y no le dedican ni 2 minutos completos. De verdad solo se va a decir, esto es encapsular, esto abstraer, esto poliformismo...?
Y la explicación? qué es? cuando se usa? cómo podemos identificar cuando usarlos? Qué desanimo
Seria bueno que los programas fueran mas interactivos, que en lugar de escribir directamente todo lo que se va a agregar se de la opción al usuario para que lo agregue y también que se explique un poco mas a fondo los pilares de POO en lugar de solo decir donde están aplicando
"""
EncapsulaciónProteger los datos de un objeto y controlar cómo se accede a ellos.Los atributos no se usan directamente desde fuera.Se accede a ellos mediante métodos(getters y setters).Ejemplo:No ves el motor del coche, solo usas el volante y los pedales.AbstracciónMostrar solo lo importante y ocultar los detalles internos.El usuario no necesita saber cómo funciona algo, solo qué hace.Se logra usando clases base o métodos que definen comportamientos generales.Ejemplo:Usas una cafetera sin saber cómo calienta el agua internamente.HerenciaReutilizar código creando nuevas clases a partir de otras.Una clase hija hereda atributos y métodos de una clase padre.Evita repetir código.Ejemplo:UnPerro y un Gato heredan de Animal.PolimorfismoUn mismo método, distintos comportamientos.Diferentes clases pueden usar el mismo método, pero con resultados distintos.Ejemplo:Todos los animales hacen sonido, pero cada uno suena distinto."""
classVehiculo: def __init__(self, marca, modelo, precio): # Encapsulación self.marca= marca
self.modelo= modelo
self.precio= precio
self.disponible=True def vender(self):if self.disponible: self.disponible=Falseprint(f"El vehículo {self.marca} ha sido vendido")else:print(f"El vehículo {self.marca} no está disponible") # Abstracción def esta_disponible(self):return self.disponible # Abstracción def obtener_precio(self):return self.precio # Métodos abstractos
def encender_motor(self): raise NotImplementedError("Este método debe ser implementado por la subclase") def apagar_motor(self): raise NotImplementedError("Este método debe ser implementado por la subclase")# HerenciaclassCoche(Vehiculo): # Polimorfismo def encender_motor(self):if not self.disponible:return f"El motor del coche {self.marca} está encendido"else:return f"El coche {self.marca} no está disponible" # Polimorfismo def apagar_motor(self):if not self.disponible:return f"El motor del coche {self.marca} se ha apagado"else:return f"El coche {self.marca} no está disponible"# HerenciaclassMotocicleta(Vehiculo): # Polimorfismo def encender_motor(self):if not self.disponible:return f"La motocicleta {self.marca} está en marcha"else:return f"La motocicleta {self.marca} no está disponible" # Polimorfismo def apagar_motor(self):if not self.disponible:return f"La motocicleta {self.marca} se ha detenido"else:return f"La motocicleta {self.marca} no está disponible"# HerenciaclassCamion(Vehiculo): # Polimorfismo def encender_motor(self):if not self.disponible:return f"El motor del camión {self.marca} está en marcha"else:return f"El camión {self.marca} no está disponible" # Polimorfismo def apagar_motor(self):if not self.disponible:return f"El motor del camión {self.marca} se ha detenido"else:return f"El camión {self.marca} no está disponible"classCliente: def __init__(self, nombre): self.nombre= nombre
self.vehiculos_comprados=[] def comprar_vehiculo(self,vehiculo:Vehiculo):if vehiculo.esta_disponible(): vehiculo.vender() self.vehiculos_comprados.append(vehiculo)else:print(f"Lo siento, {vehiculo.marca} no está disponible") def consultar_vehiculo(self,vehiculo:Vehiculo): estado ="Disponible"if vehiculo.esta_disponible()else"No disponible"print(f"El {vehiculo.marca} está {estado} y cuesta {vehiculo.obtener_precio()}")classConcesionario: def __init__(self): self.inventario=[] self.clientes=[] def agregar_vehiculo(self,vehiculo:Vehiculo): self.inventario.append(vehiculo)print(f"El {vehiculo.marca} ha sido añadido al inventario") def registrar_cliente(self,cliente:Cliente): self.clientes.append(cliente)print(f"El cliente {cliente.nombre} ha sido registrado") def mostrar_vehiculos_disponibles(self):print("Vehículos disponibles en el concesionario:")for vehiculo in self.inventario:if vehiculo.esta_disponible():print(f"- {vehiculo.marca} por {vehiculo.obtener_precio()}")# ------------------PRUEBADELPROGRAMA------------------coche1 =Coche("Toyota","Corolla",20000)moto1 =Motocicleta("Yamaha","MT-07",7000)camion1 =Camion("Volvo","FH16",80000)cliente1 =Cliente("Carlos")concesionario =Concesionario()concesionario.agregar_vehiculo(coche1)concesionario.agregar_vehiculo(moto1)concesionario.agregar_vehiculo(camion1)concesionario.mostrar_vehiculos_disponibles()cliente1.consultar_vehiculo(coche1)cliente1.comprar_vehiculo(coche1)print(coche1.encender_motor())
Ejemplo: Sistema de Cuentas Bancarias
Imaginemos que estamos desarrollando un sistema bancario donde tenemos diferentes tipos de cuentas (como cuenta de ahorros y cuenta corriente), y queremos manejar operaciones financieras como depósitos, retiros y transferencias. Vamos a aplicar los cuatro pilares de la POO en este contexto:
1. Encapsulamiento:
Creamos una clase CuentaBancaria que tiene atributos privados como saldo y titular, y solo podemos interactuar con ellos a través de métodos públicos.
Estos métodos pueden ser depositar() y retirar(), los cuales controlan cómo se actualiza el saldo. De esta forma, el saldo está protegido y no puede ser modificado directamente desde fuera de la clase.Ejemplo: Sistema de Cuentas Bancarias
Aquí, estamos encapsulando los datos sensibles (el saldo y el titular), permitiendo que solo se modifiquen a través de los métodos depositar() y retirar(), asegurando que las reglas de negocio se respeten.
-----
2. Abstracción:
Podemos crear una clase abstracta Cuenta que defina métodos comunes para todas las cuentas bancarias (como depositar() y retirar()), pero sin implementarlos.
Las clases derivadas, como CuentaCorriente y CuentaDeAhorros, implementarán estos métodos de manera específica.
La abstracción nos permite definir una estructura común sin especificar cómo se implementarán los métodos, dejando esa tarea a las clases hijas.
----
3. Herencia:
Usamos herencia para crear clases especializadas como CuentaCorriente y CuentaDeAhorros, que heredan los atributos y métodos de la clase base CuentaBancaria, pero pueden tener comportamientos específicos.
Por ejemplo, una CuentaCorriente podría permitir sobregiros, mientras que una CuentaDeAhorros podría tener restricciones sobre los retiros.
Aquí, la clase CuentaCorriente hereda todo lo de CuentaBancaria, pero modifica el método retirar() para permitir un sobregiro.
----
4. Polimorfismo:
Podemos usar polimorfismo para que ambas clases (CuentaCorriente y CuentaDeAhorros) tengan un método retirar(), pero cada uno funcione de forma diferente según el tipo de cuenta.
Por ejemplo, una CuentaDeAhorros puede no permitir sobregiros y tener límites de retiros al mes.
Aquí, el polimorfismo nos permite tener un mismo método (retirar()) con un comportamiento distinto dependiendo de si es una CuentaCorriente o una CuentaDeAhorros.
----
Resumen:
Encapsulamiento: Protegemos los datos sensibles (como el saldo) y definimos cómo interactuar con ellos.
Abstracción: Definimos métodos generales para todas las cuentas bancarias sin entrar en detalles de la implementación.
Herencia: Las cuentas específicas (como corriente y de ahorros) heredan atributos y comportamientos de una clase general (CuentaBancaria).
Polimorfismo: Permitimos que métodos como retirar() funcionen de manera diferente según el tipo de cuenta.
Este ejemplo muestra cómo puedes usar POO para modelar un sistema bancario de manera modular, clara y segura.
Aqui les dejo este ejemplo, a mi me ayudo mucho a entender los conceptos con una situacion que la mayoria vivimos en la vida real como lo es una cuenta bancaria. espero les sirva para afianzar estos conceptos. Gracias Carli por la forma como explicas y manejas las clases de verdad he aprendido como nunca.
Excelente ejemplo, muchas gracias.
Claps!
Bueno amigos, aqui tengo un programita de bibliotecas, trate de fucionar los conceptos de todas las clases de POO, espero lo ejecuten en sus computadoras y me puedan retroalimentar:
importosfrom datetime import datetime, timedelta
from abc importABC,abstractmethod
os.system('cls')classLector: def __init__(self, nombre, apellidos, cedula, convenio): self._nombre= nombre
self._apellidos= apellidos
self._cedula= cedula
self._convenio= convenio
@property
def lector(self):return f"El Usuario: {self._nombre} {self._apellidos} identificado con cedula: {self._cedula} y el convenio: {self._convenio}"
@property
def nombre(self):return self._nombre @nombre.setter def nombre(self, nuevoNombre):ifisinstance(nuevoNombre, str): self._nombre= nuevoNombre.lower()else: raise ValueError("El nombre debe ser una cadena de texto (str)")
@property
def apellidos(self):return self._apellidos @apellidos.setter def apellidos(self, nuevoApellido):ifisinstance(nuevoApellido, str): self._apellidos= nuevoApellido.lower()else: raise ValueError("El apellido debe ser una cadena de texto (str)")
@property
def cedula(self):return self._cedula @cedula.setter def cedula(self,nuevaCedula):ifisinstance(nuevaCedula, int): self._cedula= nuevaCedula
else: raise ValueError("La cedula deben ser numeros (int)") @property
def convenio(self):return self._convenio @convenio.setter def convenio(self, nuevoConvenio): convenios =["estudiante","trabajador","cotizante","independiente","gobierno"]ifisinstance(nuevoConvenio, str) and nuevoConvenio.lower()inconvenios: self._convenio= nuevoConvenio
else: raise ValueError(f"El convenio no existe, conveo valido: {','.join(convenios)}")classLibro(ABC): def __init__(self, titulo, autor, editorial, aoEdicion): self._titulo= titulo
self._autor= autor
self._editorial= editorial
self._aoEdicion= aoEdicion
@property
def titulo(self):return f"El titulo del libro es: {self._titulo}" @titulo.setter def titulo(self, nuevoTitulo):ifisinstance(nuevoTitulo, str): self._titulo= nuevoTitulo.lower()else: raise ValueError("El titulo del libro debe corresponder a una cadena")
@abstractmethod
def calcularMulta(self,dias_retraso: int)->str: pass
@abstractmethod
def obtenerInformacion(self)->str: pass
classPrestamo(Lector,Libro,ABC): def __init__(self, nombre, apellidos, cedula, convenio, titulo, autor, editorial, ao_edicion, dias_prestamo):Lector.__init__(self, nombre, apellidos, cedula, convenio)Libro.__init__(self, titulo, autor, editorial, ao_edicion) self._fecha_prestamo= datetime.now() self._fecha_devolucion= self._fecha_prestamo+timedelta(days=dias_prestamo)
@property
def infoPrestamo(self):return f"""
Lector:{self._nombre}{self._apellidos}Libro:{self._titulo}Fecha préstamo:{self._fecha_prestamo.strftime('%Y-%m-%d %H:%M:%S')}Fecha devolución:{self._fecha_devolucion.strftime('%Y-%m-%d %H:%M:%S')}"""
def calcularMulta(self,dias_retraso: int)-> float: raise NotImplementedError("Este método debe ser implementado por las subclases") def obtenerInformacion(self)-> str:return(f"Préstamo: {self._titulo} a {self._nombre} {self._apellidos}\n" f"Fecha préstamo: {self._fecha_prestamo.strftime('%Y-%m-%d')}\n" f"Fecha devolución: {self._fecha_devolucion.strftime('%Y-%m-%d')}")classPrestamoNormal(Prestamo): def calcularMulta(self,diaRetraso:int)->float:return diaRetraso *10000classPrestamoEspecial(Prestamo): def calcularMulta(self,diaRetraso:int)->float:return diaRetraso *13000classPrestamoExpress(Prestamo): def calcularMulta(self,diaRetraso:int)->float:return diaRetraso *15000# Ejemplo de uso
lector =Lector("Danny Alejandro","Fernandez Gallego",1116258606,"estudiante")print(lector.lector)prestamo =Prestamo( nombre="Juan", apellidos="Pérez López", cedula=12345678, convenio="estudiante", titulo="El Principito", autor="Antoine de Saint-Exupéry", editorial="Salamandra", ao_edicion=1943, dias_prestamo=14)# Esto ahora daría error(Libro es abstracta)# libro =Libro("Cien años...","García Márquez","Sudamericana",1967)lector1 =Lector("Luisa","Martínez",333333,"cotizante")prestamo =PrestamoExpress( nombre=lector1.nombre, apellidos=lector1.apellidos, cedula=lector1.cedula, convenio=lector1.convenio, titulo="Machine Learning", autor="Autor Z", editorial="Editorial C", ao_edicion=2022, dias_prestamo=3)print(prestamo.obtenerInformacion())print(f"Multa por 3 días de retraso: ${prestamo.calcularMulta(3):,.2f}")
no es por nada pero corriganme si estoy en lo incorrecto el encapsulamiento es encapsular los datos al exterior y solo poder acceder desde metodos por lo cual el hecho que llama encapsulamiento al crear el constructor en el video esta mal a mi parecer ya que eso se llama abstraccion al crear los atributos del objeto porque abstraes el objeto del mundo real a codigo y el encapsulamiento son los metodos get o check que define
Estas en lo correcto, incluso en el resumen escrito de la clase se aclara que el encapsulamiento es el acceso de variables privadas a traves de metodos publicos
En Python, los métodos __eq__ y __lt__ son métodos mágicos que permiten definir el comportamiento de comparación de objetos.
__eq__(self, other): Se utiliza para comparar si dos objetos son iguales. Debes definirlo en tu clase para personalizar la forma en que se compara la igualdad. Por ejemplo:
__lt__(self, other): Se utiliza para definir el comportamiento del operador menor que <. Similar al anterior, este método permite personalizar la comparación. Ejemplo:
Definir estos métodos es útil para facilitar la comparación de objetos en colecciones, ordenamientos, entre otros.
Esta clase era un buen momento para hablar acerca del principio SOLID, ya que como tal, si puedes acceder directamente a las propiedades de una instancia de una clase (Objeto). Pero no debes!
Hay una confusión entre encapsulamiento y abstracción.
Abstracción: En palabras simples es lo que hacemos cuando bajamos el problema de negocio a una definición en clases, estamos abstrayendo la funcionalidad a métodos simples. La abstracción NO es que atributos privados de un objeto no puedan verse desde un contexto publico. Abstracción es la reducción de un problema a un contrato con el cual nos comunicamos.
Encapsulamiento: El encapsulamiento, SI es el ocultamiento de detalles internos de una clase/objeto, el hacer las propiedades de un objeto privadas y definir métodos para acceder o asignar valores a ellas si es encapsulamiento. Por ejemplo en una clase persona, el color de piel podría ser una propiedad publica mientras que el nombre y la edad no, y tendrías que preguntarle a esa persona esos datos, ya que son datos que solo ella conoce. Esto pasado a código es un caso de encapsulamiento.
Nuevamente con respecto a la pregunta de la clase pasada, dices que por el pilar de la Abstracción solo se puede acceder a los atributos por los métodos públicos, pero tu accedes a ellos sin uso del método, por ejemplo en el método show_available_vehicle cuando llamas vehicle.brand.
Python se salta ese principio y no encapsula.
Hola a todos, les dejo por aquí un ejemplo simple de como seria el encapsulamiento total de un atributo al estilo Java, pero sin usar palabras reservadas como Public o Private, ya que en python se siguen convenciones de nombres, se usa el doble guion bajo "__" para definir como privado un atributo:
classUsuario:def__init__(self, nombre):# Atributo privado: no se puede acceder como .__nombre desde fuera self.__nombre = nombre
@propertydefnombre(self):return self.__nombre.capitalize()@nombre.setterdefnombre(self, valor):iflen(valor)<3:raise ValueError("El nombre es muy corto") self.__nombre = valor
# --- Uso ---user = Usuario("ana")# 1. Acceso a través del "método computado" (Getter)print(user.nombre)# Salida: Ana# 2. Intento de acceso directo al atributo privado (Dará error)# print(user.__nombre) # AttributeError: 'Usuario' object has no attribute '__nombre'# 3. Modificación protegida (Setter)user.nombre ="marta"print(user.nombre)# Salida: Marta
Sí, puedes integrar un chatbot programado en HTML, JavaScript y Python en otras páginas HTML. Puedes hacerlo creando una API en Python que se ejecute en el backend y que interactúe con tu chatbot. Luego, en tus otras páginas HTML, puedes usar JavaScript para hacer solicitudes HTTP a esa API y obtener respuestas. Esto permite que solo necesites añadir un pequeño fragmento de código JavaScript en tus otras páginas para conectar con el chatbot. Asegúrate de manejar adecuadamente las peticiones y respuestas entre el frontend y el backend.