Fundamentos de Programación y Python

1

Fundamentos de Programación con Python: Tipos y Paradigmas

2

Instalación de Python en Windows y Mac

3

Sintaxis y Semántica en Python: Comprensión y Aplicaciones

4

Práctica: Te doy la bienvenida a los ejercicios interactivos

5

Manipulación de Cadenas en Python: Comillas, Indexación y Métodos

6

Variables y Tipos de Datos en Python: Enteros, Flotantes y Booleanos

7

Técnicas avanzadas de impresión con `print` en Python

8

Operadores Matemáticos y Booleanos en Python

9

Manejo de Input en Python: Variables, Casting y Tipos de Datos

Colección y Procesamiento de Datos en Python

10

Manipulación de Listas en Python: Métodos y Funciones Básicas

11

Copiar listas en Python: referencias vs slicing

12

Matrices y Tuplas en Python: Manipulación y Acceso de Datos

13

Matrices en Python para Tableros de Juegos y Más

14

Manipulación de diccionarios en Python: claves, valores y métodos

Control de Flujo en Python

15

Condicionales en Python: if, elif, else y combinaciones lógicas

16

Bucles e Iteraciones: For y While en Python

17

Generadores e iteradores en Python: eficiencia en manejo de datos

18

Comprensión de Listas en Python: Cómo Usarlas y Cuándo Aplicarlas

Funciones y Manejo de Excepciones en Python

19

Uso de Funciones en Python para Dividir y Optimizar Código

20

Funciones Lambda en Python: Operaciones y Filtrado Eficiente

21

Recursividad en Python: Factoriales y Fibonacci

22

Manejo de Excepciones en Python: Identificación y Solución de Errores

Programación Orientada a Objetos en Python

23

Manipulación de Cuentas Bancarias con Clases en Python

24

Creación de Clases en Python: Biblioteca, Libros y Usuarios

25

Herencia en Programación con Python: Vehículos y Clases Derivadas

26

Clase Python: Herencia y Polimorfismo en Vehículos

27

Programación Orientada a Objetos: Polimorfismo en Acción

28

Uso de super() para herencia en clases Python

29

Uso de `super()` para Heredar Métodos en Python

Lectura y escritura de archivos

30

Tratamiento de Archivos TXT en Python: Lectura y Escritura

31

Manipulación de archivos CSV con Python: lectura y escritura efectiva

32

Manejo de Archivos JSON en Python: Lectura y Escritura

Biblioteca estándar de Python

33

Programación Eficiente con la Biblioteca Estándar de Python

34

Uso de Librerías OS, Math y Random en Python

35

Análisis de datos de ventas con Python y librería Statistics

36

Programación del Juego Batalla Naval en Python

Conceptos avanzados de Python

37

POO: Diseño de Clases y Objetos en Python

38

Buenas prácticas en Python: código limpio y eficiente

39

Comentarios y Docstrings: Buenas Prácticas en Python

40

Variables locales y globales en Python

41

Anotaciones de tipo en Python: mejora la legibilidad del código

42

Validación de tipos de datos en Python: Técnicas y buenas prácticas

43

Estructuras de Datos Avanzadas en Collections y Enum en Python

Decoradores

44

Decoradores en Python: Añadir Funcionalidad sin Modificar Código

45

Uso de Decoradores Anidados y con Parámetros en Python

46

Decoradores en Python: Staticmethod, Classmethod y Property

Métodos y estructura de clases en Python

47

Métodos Mágicos en Python: Personalización de Clases y Objetos

48

Sobrecarga de Operadores en Python: Sumando e Igualando Objetos

49

Uso de "__name__ == '__main__'" en Scripts Python

50

Programación Orientada a Objetos en Python: Métodos `__init__` y `__new__`

51

Funcionamiento de ARGS y KWARGS en Python

52

Métodos y Atributos Privados en Python

53

Uso del decorador property en Python para atributos privados

54

Métodos estáticos y de clase en Python: prácticas avanzadas

Programación concurrente y asíncrona

55

Concurrencia y paralelismo en Python: manejo eficiente de procesos

56

Concurrente: Hilos y Procesos en Python

57

Técnicas de Asincronismo en Python: Uso de AsyncIO y Corrutinas

58

Concurrencia y Asincronía en Python para Gestión de Pedidos

Creación de módulos y paquetes

59

Módulos y paquetes en Python: reutilización de código eficiente

60

Uso de Paquetes y Subpaquetes en Python

61

Publicación de paquetes en PyPI: guía paso a paso

Proyecto final

62

Sistema de Gestión de Reservas de Hotel con Python

63

Gestión de Reservas de Hotel con Python Avanzado

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Python

Curso de Python

Carli Code

Carli Code

Programación Orientada a Objetos: Polimorfismo en Acción

27/63
Recursos

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.

Aportes 38

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

* Encapsulamiento:* Agrupa datos y métodos relacionados en una clase. * Oculta los detalles internos y controla el acceso a los datos. * Ejemplo: Una clase "Coche" que encapsula propiedades como "color" y métodos como "arrancar". * Abstracción:* Simplifica sistemas complejos ocultando detalles innecesarios. * 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.
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
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.
### 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.
Esto me ayudo a aclarar dudas respecto al polimorfismo, ya que era el pilar mas abstracto para mi. :D ## `Ventajas del Polimorfismo:` 1. `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.` 2. `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.` 3. `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:` 1. `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.` 2. `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.`
```python #Excelente clase! Super dinámica. #Ejercicio Finalizado class Vehicle: def __init__(self,brand,model,price): #Encapsulación self.brand = brand self.model = model self.price = price self.is_available = True def sell(self): if self.is_available: self.is_available = False print(f"El vehiculo {self.brand}. Ha sido vendido.") else: print(f"El vehiculo {self.brand}. No está vendido.") #Abstracción def check_available(self): return self.is_available #Abstracción def get_price(self): return self.price def start_engine(self): raise NotImplementedError("Este método debe ser implementado por la subclase") def stop_engine(self): raise NotImplementedError("Este método debe ser implementado por la subclase") #Herencia class Car(Vehicle): #Polimorfismo def start_engine(self): if not self.is_available: return f"El motor del coche {self.brand} está en marcha." else: return f"El coche {self.brand} no está disponible." #Polimorfismo def stop_engine(self): if not self.is_available: return f"El motor del coche {self.brand} se ha detenido." else: return f"El coche {self.brand} no está disponible." class Bike(Vehicle): def start_engine(self): if not self.is_available: return f"La bicicleta {self.brand} está en marcha." else: return f"La bicicleta {self.brand} no está disponible." def stop_engine(self): if not self.is_available: return f"La bicicleta {self.brand} se ha detenido." else: return f"La bicicleta {self.brand} no está disponible." class Truck(Vehicle): def start_engine(self): if not self.is_available: return f"El motor del camión {self.brand} está en marcha." else: return f"El camión {self.brand} no está disponible." def stop_engine(self): if not self.is_available: return f"El motor del camión {self.brand} se ha detenido." else: return f"El camión {self.brand} no está disponible." class Customer: def __init__(self,name): self.name = name self.purchased_vehicles = [] def buy_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.") def inquire_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()}.") class Dealership: def __init__(self): self.inventory = [] self.customers = [] def add_vehicles(self, vehicle: Vehicle): self.inventory.append(vehicle) print(f"El {vehicle.brand} ha sido añadido al inventario.") def register_customers(self, customer: Customer): self.customers.append(customer) print(f"El cliente {customer.name} ha sido añadido.") def show_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 disponibles dealership.show_available_vehicle() #Cliente consultar un vehiculo customer1.inquire_vehicle(car1) #Cliente comprar un vehiculo customer1.buy_vehicle(car1) #Mostrar vehiculos disponibles dealership.show_available_vehicle() ```
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
👌🏼 Aplico muy bien el polimorfismo, porque la Bicicleta se convirtio en Motocicleta 🏍️ 😅
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
**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** ![](https://static.platzi.com/media/user_upload/image-18d18c46-d9fe-4bd6-8f17-84725fa08fcf.jpg) 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. ![](https://static.platzi.com/media/user_upload/image-f7015cce-b7b6-4ca5-8d0f-06c43b474b0d.jpg) 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. ![](https://static.platzi.com/media/user_upload/image-bb9cd04b-c3e6-4202-b65b-b54b62b30691.jpg) 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. ![](https://static.platzi.com/media/user_upload/image-9e50322d-97cb-4777-80bc-00b56b103b79.jpg) 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.
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
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.
Acotación sobre Polimorfismo: El objetivo del polimorfismo es poder establecer un comportamiento dinámico de un método o una clase., de allí que se considera como poli (múltiples / muchas) - morfo (forma) // múltiples formas. Un método de una clase Base puede ser implementado de distintas maneras por otras clases que deriven de ella. En otros lenguajes, como Java o C#, esto se logra por distintos modos: * **\<u>Por herencia:\</u>** una clase derivada (hija) implementa el método de la clase Base (Padre) de manera especifica. Puedes usar clases Abstractas, aunque Python te permite declarar un método sin implementación usando "pass"; sin necesidad de declarar la clase ni el método como abstracto. * **\<u>Implementando una Interfaz\</u>**: En Python no existe el término Interface, pero se puede usar lo que se conoce como Clase Abstracta (usada en lenguajes como C# o Java). En Python, una clase Abstracta representa el concepto de Abstracción y permite tener métodos abstractos que requieren ser implementados. En Python, para declarar una **clase abstracta** y sus **métodos abstractos**, usamos el módulo `abc` (Abstract Base Classes). Las clases abstractas sirven como **plantillas**: no se pueden instanciar directamente (no se pueden crear objetos) y obligan a las subclases a implementar ciertos métodos. ### Para declarar una clase abstracta en Python: 1. Importar desde el módulo `abc` 2. Heredar de `ABC` 3. Usar el decorador `@abstractmethod` para métodos que deben implementarse. Aquí un ejercicios usando Herencia, Clase Abstracta y Polimorfismo, haciendo uso de una clase abstracta Base "Heroe", una clase hija llamada "Superheroe" y otra llamada "Antiheroe". Aquí ambas clases "Superheroe" y "Antiheroe" pueden implementar de distinta manera los métodos \<combatir\_enemigos()> y \<mostrar\_poderes()>. Cada clase puede definir sus propias implementaciónes, por mas que sean similares, de allí el llamado "POLIMORFISMO". ```js from abc import ABC, abstractmethod class Heroe(ABC): def __init__(self, nombre, identidad_secreta): self.__nombre = nombre self.__identidad_secreta = identidad_secreta self.lista_enemigos = [] self.lista_poderes = [] def nombre(self): return self.__nombre @abstractmethod def combatir_enemigos(self): pass @abstractmethod def mostrar_poderes(self): pass def ayudar_personas(self, mensaje): pass class SuperHeroe(Heroe): def combatir_enemigos(self): print(f"{self.nombre()} puede combatir enemigos.") if(len(self.lista_enemigos)>0): for enemigo in self.lista_enemigos: print(f"El super-héroe {self.nombre()} tiene como enemigo {enemigo}") else: print(f"El super-héroe {self.nombre()} no tiene enemigos") def mostrar_poderes(self): if(self.lista_poderes is not None): for superpoder in self.lista_poderes: print(f"El super-héroe {self.nombre()} tiene superpoder {superpoder}") else: print(f"El super-héroe {self.nombre()} no tiene superpoderes") def ayudar_personas(self, mensaje): print(f"{self.nombre()} {mensaje}") class Antiheroe(Heroe): def combatir_enemigos(self): print(f"{self.nombre()} puede combatir enemigos.") print("Tiene varios enemigos, entre ellos los propios súper-heroes.") def mostrar_poderes(self): print("Tiene varios poderes, incluso son mas poderosos que un súper-heroe.") if(self.lista_poderes is not None): for superpoder in self.lista_poderes: print(f"El super-héroe {self.nombre()} tiene superpoder {superpoder}") else: print(f"El super-héroe {self.nombre()} no tiene superpoderes") superman = SuperHeroe("Superman","Clark Kent") enemigos_superman = ["Lex Luthor","Zod","Darkseid"] super_poderes_superman = ["Súper fuerza","Velocidad","Volar","Visión microscópica","Súper Audición"] superman.lista_enemigos = enemigos_superman superman.lista_poderes = super_poderes_superman wolverine = SuperHeroe("Wolverine","Logan") enemigos_wolverine= ["Jocker","El Pingüino.","Dos caras","Enigma"] super_poderes_wolverine= ["Fuerza sobrehumana","Huesos indestructibles","Garras retráctiles","Factor de curación"] wolverine.lista_enemigos = enemigos_wolverine wolverine.lista_poderes = super_poderes_wolverine dardevil = Antiheroe("Daredevil","Matt Murdock") poderes_dardevil = ["Sentidos sobrehumanos","Ecolocalización","Ausencia de miedo","Regeneración"] dardevil.lista_poderes = poderes_dardevil superman.combatir_enemigos() superman.mostrar_poderes() superman.ayudar_personas("ayuda a la personas del mundo") wolverine.combatir_enemigos() wolverine.mostrar_poderes() dardevil.combatir_enemigos() dardevil.mostrar_poderes() ```![](https://static.platzi.com/media/user_upload/upload-36ac48cb-b84c-46b8-85ba-d417cd9a68f5.png)
Sólo una aclaración: En la descripción de la clase, en la definición de ENCAPSULAMIENTO, se define correctamente el término, pero indican: "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"` En realidad, en el código no se ha definido ningún atributo o método privado, todos han sido públicos. Que el precio y el estado pueden ser privados, por supuesto, para acceder a ellos mediante sus métodos públicos. **Sin embargo, hago la aclaración.** Sintaxis en Python: * **public** ---> nombre (sin guiones bajos) * **protected** ---> \_nombre (con un subguión bajo al inicio) * private ---> \_\_nombre (con dos subguiones bajos al inicio) En Python no hay **modificadores de acceso estrictos** como en Java o C++, pero **sí existen convenciones** para indicar si un atributo o método debe ser **público**, **protegido** o **privado**. Conceptos: * **<u>Privado</u>**: Solo se puede acceder a dichos elementos en el ámbito de la clase contenedora (uso interno). Es decir, no puede invocarla desde otra clase e incluso ni siquiera desde la instancia (objeto) de la misma clase contenedora. Solo puedo acceder desde otros métodos o propiedades dentro de la misma clase donde se ha definido el elemento privado. * **<u>Protected</u>**: Esto es algo similar a la definición en c#. Puedo acceder desde la clase contenedora o desde las subclases derivadas de la clase contenedora. Sin embargo, en Python, técnicamente sí te permite acceder a una variable definida como protected (\_variable) pero no es aconsejable. * Público: El elemento definido como público puede ser accedido por cualquier otra clase. En C# se dice que un elemento definido como público puede ser accedido por cualquier otra clase dentro de el ensamblado actual o cualquier otro ensamblado. ![](https://static.platzi.com/media/user_upload/upload-f966c63b-af2c-4643-9397-465165492038.png)
<"""LOS 4 PILARES DE LA POO:1. Abstraccion     - Simplificar un concepto del mundo real.2. Encapsulamiento - Proteger los datos internos.3. Herencia        - Reutilizar y extender funcionalidad.4. Polimorfismo    - Mismo metodo, diferentes comportamientos.""" \#    1. ABSTRACCION   # La clase Animal representa un concepto general, # con solo los atributos/metodos esenciales.class Animal:         def \_\_init\_\_(self, nombre): #    2. ENCAPSULAMIENTO          self.\_\_nombre = nombre  # Usamos \_\_ para encapsular el nombre.                               #    4. POLIMORFISMO (metodo base)      def hacer\_sonido(self):   # metodo que las subclases pueden redefinir.        return "Sonido genérico"     # metodo comun que usa el atributo encapsulado.    def decir\_nombre(self):        return f"Mi nombre es {self.\_\_nombre}" \#    3. HERENCIA   # Perro ES UN Animal (hereda atributos y metodos).class Perro(Animal): #usar la superclase o clase padre como parametro en la clase hija para que herede       def hacer\_sonido(self):  # Redefinimos el metodo para cambiar el comportamiento (POLIMORFISMO).        return " Guau "      # es el mismo metodo pero cambia el return (comportamiento cambia) class Gato(Animal):    def hacer\_sonido(self):        return " Miau " \#     USO    if \_\_name\_\_ == "\_\_main\_\_": # definimos nuevos objetos, no clases objetos    # Creamos un Perro (que ES UN Animal).    mi\_perro = Perro("Dinno")    mi\_gato = Gato("Queen")     # Llamamos a los metodos    print(mi\_perro.hacer\_sonido())      print(mi\_gato.hacer\_sonido())       # Accedemos al metodo comun heredado.    print(mi\_perro.decir\_nombre())  >
La herencia en Python es un principio de la programación orientada a objetos que permite crear nuevas clases (clases hijas) basadas en clases existentes (clases padres). Esto promueve la reutilización del código, ya que las clases hijas heredan atributos y métodos de las clases padres. Por ejemplo, una clase `Auto` puede heredar de una clase `Vehículo`, obteniendo propiedades como `marca` y `modelo`, lo que permite crear un sistema estructurado y eficiente. Este concepto es clave para implementar polimorfismo y encapsulación en Python.
```python # 1. Abstracción # Es el proceso de ocultar los detalles internos de una clase y mostrar solo la funcionalidad esencial. # En Python, se logra mediante clases abstractas usando el módulo abc. # Ejemplo de Abstracción from abc import ABC, abstractmethod class Animal(ABC): # Clase abstracta que define la estructura básica de un Animal. # Sirve como modelo para que las subclases implementen sus propios comportamientos. @abstractmethod def hacer_sonido(self): pass # Método abstracto que debe ser implementado por cualquier subclase. # Define el sonido característico del animal. # Retorna: # str: Sonido que hace el animal. # No se implementa aquí, solo se define su existencia class Perro(Animal): # Clase que representa un Perro, heredando de la clase abstracta Animal. def hacer_sonido(self): return "Guau Guau" # Implementación del método abstracto hacer_sonido para Perro. # Retorna: # str: Sonido característico del perro. class Gato(Animal): # Clase que representa un Gato, heredando de la clase abstracta Animal. def hacer_sonido(self): return "Miau Miau" # Implementación del método abstracto hacer_sonido para Gato. # Retorna: # str: Sonido característico del gato. class Vaca(Animal): # Clase que representa un Gato, heredando de la clase abstracta Animal. def hacer_sonido(self): return "Muu Muu" # Implementación del método abstracto hacer_sonido para Gato. # Retorna: # str: Sonido característico del gato. # Uso de las clases vaca = Vaca() # Se crea una instancia de Perro print(f"La vaca hace: {vaca.hacer_sonido()}") # Salida: Muu Muu perro = Perro() # Se crea una instancia de Perro print(f"El perro hace: {perro.hacer_sonido()}") # Salida: Guau Guau gato = Gato() # Se crea una instancia de Gato print(f"El gato hace: {gato.hacer_sonido()}") # Salida: Miau Miau # No se puede instanciar la clase Animal porque es abstracta # animal = Animal() # Esto generaría un error ```# 1. Abstracción \# Es el proceso de ocultar los detalles internos de una clase y mostrar solo la funcionalidad esencial. # En Python, se logra mediante clases abstractas usando el módulo abc. \# Ejemplo de Abstracciónfrom abc import ABC, abstractmethod class Animal(ABC):   # Clase abstracta que define la estructura básica de un Animal.   # Sirve como modelo para que las subclases implementen sus propios comportamientos.     @abstractmethod    def hacer\_sonido(self):        pass       #   Método abstracto que debe ser implementado por cualquier subclase.     #   Define el sonido característico del animal.     #   Retorna:     #   str: Sonido que hace el animal.     # No se implementa aquí, solo se define su existencia class Perro(Animal):   # Clase que representa un Perro, heredando de la clase abstracta Animal.    def hacer\_sonido(self):        return "Guau Guau"     #   Implementación del método abstracto hacer\_sonido para Perro.     #   Retorna:     #   str: Sonido característico del perro.     class Gato(Animal): #   Clase que representa un Gato, heredando de la clase abstracta Animal.    def hacer\_sonido(self):        return "Miau Miau" #       Implementación del método abstracto hacer\_sonido para Gato. #       Retorna: #       str: Sonido característico del gato. class Vaca(Animal): #   Clase que representa un Gato, heredando de la clase abstracta Animal.    def hacer\_sonido(self):        return "Muu Muu" #       Implementación del método abstracto hacer\_sonido para Gato. #       Retorna: #       str: Sonido característico del gato. \# Uso de las clasesvaca = Vaca()  # Se crea una instancia de Perroprint(f"La vaca hace: {vaca.hacer\_sonido()}")  # Salida: Muu Muu perro = Perro()  # Se crea una instancia de Perroprint(f"El perro hace: {perro.hacer\_sonido()}")  # Salida: Guau Guau gato = Gato()  # Se crea una instancia de Gatoprint(f"El gato hace: {gato.hacer\_sonido()}")  # Salida: Miau Miau \# No se puede instanciar la clase Animal porque es abstracta# animal = Animal()  # Esto generaría un error
El principio SOLID es un acrónimo que representa cinco principios fundamentales para la programación orientada a objetos que buscan hacer el código más comprensible y flexible. Estos son: 1. **S** - Single Responsibility Principle: Una clase debe tener una única razón para cambiar. 2. **O** - Open/Closed Principle: Las clases deben estar abiertas a la extensión, pero cerradas a la modificación. 3. **L** - Liskov Substitution Principle: Las subclases deben ser sustituibles por sus clases base. 4. **I** - Interface Segregation Principle: No se debe forzar a un cliente a depender de interfaces que no utiliza. 5. **D** - Dependency Inversion Principle: Las dependencias deben depender de abstracciones y no de implementaciones concretas. ### Ejemplo del principio SOLID en Python: ```python # Principio de Responsabilidad Única class Usuario: def __init__(self, nombre): self.nombre = nombre def mostrar_nombre(self): print(f"Nombre: {self.nombre}") def guardar_usuario(self): # lógica para guardar el usuario en una base de datos pass # Aquí, la clase Usuario tiene una única responsabilidad: # Manejar la información del usuario. # Aplicando el principio de Abierto/Cerrado class Impresora: def imprimir(self, documento): print(f"Imprimiendo: {documento}") # La clase Impresora se puede extender sin modificarla class ImpresoraPDF(Impresora): def imprimir(self, documento): print(f"Imprimiendo PDF: {documento}") # La clase base Impresora no se modifica, pero se puede extender. ``` Este ejemplo ilustra cómo aplicar algunos de los principios SOLID en Python, mejorando la estructura y la mantenibilidad del código, lo que es esencial en proyectos de programación orientada a objetos.
Una instancia es un objeto creado a partir de una clase en programación orientada a objetos. Cada instancia tiene sus propios atributos y métodos definidos por la clase, lo que permite representar conceptos del mundo real de manera programática. Por ejemplo, si tienes una clase "Auto", cada auto que creas (como un Toyota Corolla) es una instancia de esa clase, con atributos específicos como marca y modelo. Esto permite organizar y gestionar datos de manera efectiva en tu código.
En la programación orientada a objetos, la línea `dealership = Dealership()` crea una instancia de la clase `Dealership`. Esto significa que estás construyendo un objeto concreto a partir de la plantilla (o clase) definida previamente. La instancia `dealership` podrá tener sus propios atributos y métodos, y se usará para interactuar con el objeto en el código. Esta práctica es fundamental para aplicar la encapsulación, uno de los pilares de la programación orientada a objetos, permitiendo manejar datos y comportamientos de forma organizada y eficiente.
### 7.4 Los 4 pilares de la Programación Orientada a Objetos POO Los pilares de POO son fundamentales para crear código organizado y mantenible. Veamos cada uno con ejemplos prácticos usando una tienda de dulces: ### 1. Abstracción Es el proceso de simplificar la realidad, tomando solo los aspectos relevantes para nuestro programa. En otras palabras, nos permite crear modelos simples de objetos complejos. class Dulce: def \_\_init\_\_(self, nombre, precio, peso): self.nombre = nombre self.precio = precio self.peso = peso def obtener\_precio\_total(self): return self.precio \* self.peso ### 2. Encapsulamiento Nos permite ocultar detalles internos y proteger la integridad de los datos. Usando modificadores de acceso (private, public) controlamos qué información es accesible. class CajaRegistradora: def \_\_init\_\_(self): self.\_\_total\_ventas = 0 # Privado self.ventas\_del\_dia = 0 # Público def registrar\_venta(self, monto): self.ventas\_del\_dia += monto self.\_\_total\_ventas += monto def obtener\_total\_ventas(self, codigo\_gerente): if codigo\_gerente == "123": return self.\_\_total\_ventas return "Acceso denegado" ### 3. Polimorfismo Permite que objetos de diferentes clases respondan al mismo método de diferentes maneras. Es como tener diferentes tipos de dulces que se venden de forma distinta. class Chocolate(Dulce): def vender(self): return f"Vendiendo {self.nombre} por unidad a ${self.precio}" class Caramelo(Dulce): def vender(self): return f"Vendiendo {self.nombre} por peso: ${self.precio} x {self.peso}kg" \# Puedo usar cualquier tipo de dulce def procesar\_venta(dulce): return dulce.vender() # Cada dulce se vende diferente ### 4. Herencia Permite crear nuevas clases basadas en clases existentes, heredando sus atributos y métodos. Es como tener una clase general "Dulce" y crear tipos específicos. class Chocolate(Dulce): def \_\_init\_\_(self, nombre, precio, peso, porcentaje\_cacao): super().\_\_init\_\_(nombre, precio, peso) # Heredo de la clase padre self.porcentaje\_cacao = porcentaje\_cacao class Gomita(Dulce): def \_\_init\_\_(self, nombre, precio, peso, sabor, forma): super().\_\_init\_\_(nombre, precio, peso) self.sabor = sabor self.forma = forma
Mi resumen: Herencia: Es la capacidad que tiene una clase de acceder a los métodos y variables de otra clase que sirve como base. Abstracción: Es la capacidad que solo tienen los métodos de acceder a las variables internas. Encapsulamiento: Hace referencia a las variables y métodos privados contenidos por una clase. Polimorfismo: Es la capacidad de cambiar el funcionamiento de un método. Sin alterar el codigo base.
* Los **cuatro pilares de la programación orientada a objetos (POO)** son principios fundamentales que sustentan este paradigma. Estos son: ### 1. **Abstracción** * **Definición:** Se enfoca en mostrar únicamente los detalles esenciales de un objeto y ocultar la complejidad innecesaria. * **Propósito:** Simplificar el diseño del programa al centrarse en *qué* hace un objeto en lugar de *cómo* lo hace. * **Ejemplo:** Una clase `Carro` podría abstraer detalles como el método `conducir()` en lugar de exponer el funcionamiento interno del motor. ### 2. **Encapsulación** * **Definición:** Consiste en restringir el acceso directo a ciertos componentes de un objeto y protegerlos del exterior, proporcionando métodos controlados para interactuar con ellos. * **Propósito:** Asegurar la integridad de los datos, evitando modificaciones no deseadas. * **Ejemplo:** Utilizar modificadores de acceso como `private`, `protected` y `public` para controlar qué atributos o métodos son accesibles. ### 3. **Herencia** * **Definición:** Permite que una clase (hija) adquiera los atributos y métodos de otra clase (padre). * **Propósito:** Reutilizar código y establecer una jerarquía entre objetos. * **Ejemplo:** Una clase `Vehículo` puede ser la base para clases como `Carro` y `Moto`, compartiendo atributos comunes como `ruedas` y `motor`. ### 4. **Polimorfismo** * **Definición:** Permite que los métodos en diferentes clases compartan el mismo nombre, pero se comporten de manera diferente según el contexto. * **Propósito:** Hacer que el código sea más flexible y extensible. * **Ejemplo:** Un método `moverse()` puede comportarse distinto en las clases `Carro` y `Avión`, adaptándose a las características de cada clase.
Los 4 pilares de la programacion orientada a objetos: Te los preguntan en entrevistas tecnicas inquire es preguntar en forma de consulta, como business inquires
Haber estas ultimas clases con el ejercicio de la concesionaria estuvieron un tanto confusas se entiende q estamos haciendo lo mismo q el ejercicio de la biblioteca pero agregando herencias, y conceptos de POO, abstracción y polimorfismo los cuales creo q se podrían abordar de mejor manera con un poco mas de explicación detallada por ejemplo: En la herencia bicicleta ya no usamos un constructor si no q nos enfocamos en realizar las diferentes funciones q tiene esta clase ya que los atributos como son Marca. Precio y Modelo los tenemos en la clase principal y por lo tanto ya no es necesario volverlos a poner en la clase bicicleta para no redundar datos y así con las demás. Por otro lado creo q se entendería mejor estas ultimas 3 clases si estuvieran en un solo video y mejor estructurado, por lo demás al verlo varias veces y repasar los conceptos de los pilares de la POO ya se entiende muy bien todo el ejercicio y las cosas a las que se refiera la Profesora. No se si me di a entender pero lo explique lo mejor que puede es una sugerencia y disculpen cualquier error cometido en mi explicación gracias por leer
Los tres pilares de la programación orientada a objetos son: 1. **Abstracción**: Permite simplificar la complejidad al enfocarse solo en los aspectos relevantes del objeto, ocultando los detalles innecesarios. 2. **Encapsulamiento**: Protege el estado interno del objeto, permitiendo acceso a los atributos solo a través de métodos definidos, asegurando que la interacción sea controlada. 3. **Polimorfismo**: Permite que diferentes clases respondan a la misma interfaz de métodos, brindando flexibilidad y reutilización del código. Estos pilares son fundamentales para diseñar aplicaciones robustas y mantenibles.
El polimorfismo en programación orientada a objetos permite que diferentes clases respondan a la misma acción de maneras distintas. Ejemplo con personas y animales: 1. Clase base: `Animal` con método `hacerSonido()`. 2. Clases derivadas: - `Perro` que implementa `hacerSonido()` como "guau". - `Gato` que implementa `hacerSonido()` como "miau". - `Persona` que implementa `hacerSonido()` como "habla". Al invocar `hacerSonido()` en una instancia de `Animal`, el comportamiento dependerá del tipo de objeto: un perro ladrará, un gato maullará y una persona hablará. Este concepto permite usar el mismo método para diferentes tipos de objetos y obtener resultados específicos.
Este lenguaje de programación no tiene campos/métodos privados/protegidos ¿Donde está la abstracción aquí? ![](https://static.platzi.com/media/user_upload/image-790d416d-fe7c-4ebf-948e-2d96f70815ad.jpg)
Hola, me costó un poco entender los 4 pilares de la POO, así que dejaré este comentario por si le sirve a alguien: 1. Herencia: Las clases hijas heredan todos los atributos y métodos de la clase padre, entonces si tengo la clase padre Animal((self, raza, peso, nombre, edad), las hijas Perro, Gato, Tigre, Hamster, etc también tendrán los atributos de Animal: self, raza, peso, nombre, edad 2. Encapsulamiento: Básicamente se definen variables privadas con "\_\_" antes del nombre de la variable. Si bien esta variable es privada y no puedo acceder a ella directamente con un print() por ejemplo, si puedo utilizarla en los métodos de la clase, y por ende, también puedo acceder a su valor, pero a través de un método, como sería obtener\_saldo. 3. Polimorfismo: En los métodos de la clase padre (abstractos) puedo indicar pass o tambien return "algo" para asignar valores por defecto, es decir, las clases hija PUEDEN O NO sobreescribir los métodos de la clase padre. Y puedo crear objetos de la clase padre 4. Abstracción: Es muy similar al polimorfismo, pero en los métodos debo si o si indicar pass porque su comportamiento es propio de cada clase hija. Además En las clases hija, DEBO SI O SI definir el comportamiento de los métodos que están en la clase padre, cada uno a su manera, pero es obligatorio, es decir, las clases hijas DEBEN implementar TODOS los métodos abstractos. Espero les sirva! (el otro comentario me quedó con un formato feisimo por eso lo reescribi)
Hola, me costó un poco entender los 4 pilares de la POO, así que dejaré este comentario por si le sirve a alguien: Herencia: Las clases hijas heredan todos los atributos y métodos de la clase padre, entonces si tengo la clase padre Animal, las hijas Perro, Gato, Tigre, Hamster, etc también tendrán los atributos de Animal (self, raza, peso, nombre, edad)```js class Animal: def __init__(self, raza, peso, nombre, edad) ```2. Polimorfismo: Si en la clase padre defino un método abstracto (ej: def hacer sonido(self):), indico que todos los animales PUEDEN hacer un sonido, pero no es obligatorio, por ende lo sigo de un pass o return, en caso de usar return sería un valor de saida por defecto. Las clases hijas puedne o no sobreescribir los métodos de la clase padre (en el ejemplo hacer sonido, puedo dejar el valor defecto o especificarlo). Puedo crear objetos de la clase padre 1.
Encapsulamiento en Python (Copilot) En Python, el encapsulamiento no es tan estricto como en Java o C++. Python utiliza convenciones de nombres para indicar que un atributo es privado, pero no impide completamente el acceso a estos atributos. Se utiliza un guion bajo doble (\_\_) para indicar que un atributo es privado, y Python aplica un renombramiento de atributos (name mangling) para dificultar el acceso directo. En el siguiente ejemplo se podria acceder al atributo privado utilizando un nombre renombrado. \# class Ejemplo: def \_\_init\_\_(self): self.publico = "Soy público" self.\_protegido = "Soy protegido" self.\_\_privado = "Soy privado" def mostrar\_privado(self): return self.\_\_privado obj = Ejemplo() print(obj.publico) # Soy público print(obj.\_protegido) # Soy protegido \#print(obj.\_\_privado) # AttributeError: 'Ejemplo' object has no attribute '\_\_privado' print(obj.mostrar\_privado()) # Soy privado
Mi aporte de estos conceptos en mis propias palabras: * **Herencia**: Una subclase hereda los atributos y métodos de la superclase. * **Encapsulamiento**: Hace privados los atributos de una clase, de tal manera que solo esa clase pueda acceder o modificarlos. * **Abstracción**: Mostrar solo los métodos más importantes de un objeto y ocultar detalles complicados de su implementación. * **Polimorfismo**: Permite que un mismo método actúe de manera diferente según el objeto que lo implemente.
Creo que se ha olvidado de registrar al cliente
fue algo complicado comprender el encapsulamiento en python, sobretodo si lo aprendiste en otro lenguaje, pero por lo que lei en python no existe el encansulamiento como tal, solo se puede ocultar los metodos y atributos usando un doble guion bajo (\_\_nombre\_metodo), para volverlo privado y que solo sea accesible para la clase que lo contiene
Debo admitir yo ya conocia estos 4 pace mucho tiempo y los entendia, pero la manera en la cual la profesora los explica, la hace entender super facil.
Me encanta la manera en que haz explicado, fue mucho más fácil entenderlo como lo explicaste tu a la forma que me enseñaron en la universidad. Muchas gracias!