0% encontró este documento útil (0 votos)
4 vistas28 páginas

POO en Python: Clases y Herencia

Cargado por

colegiooscuro99
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
4 vistas28 páginas

POO en Python: Clases y Herencia

Cargado por

colegiooscuro99
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

# **Capítulo 4: Programación orientada a objetos en Python**

## **Página 1: Introducción a la POO**

### ¿Qué es la Programación Orientada a Objetos?

La POO es un paradigma de programación que organiza el código alrededor de objetos


y clases, en lugar de funciones y procedimientos. Python es un lenguaje
multiparadigma que soporta completamente la POO.

### Conceptos fundamentales:

- **Clase**: Molde o plantilla para crear objetos

- **Objeto**: Instancia específica de una clase

- **Atributos**: Características o propiedades del objeto

- **Métodos**: Comportamientos o acciones del objeto

### Pilares de la POO:

1. **Encapsulación**: Ocultar detalles internos

2. **Herencia**: Crear nuevas clases basadas en existentes

3. **Polimorfismo**: Mismo interfaz, diferentes implementaciones

4. **Abstracción**: Simplificar la complejidad

### Ventajas de la POO:

- Código más organizado y reutilizable

- Facilita el mantenimiento

- Modela mejor el mundo real

- Promueve la modularidad

---
## **Página 2: Clases y objetos**

### Definición de una clase:

```python

class Perro:

"""Clase que representa un perro"""

# Atributo de clase (compartido por todas las instancias)

especie = "Canis lupus familiaris"

def __init__(self, nombre, raza, edad):

"""Método constructor - inicializa el objeto"""

# Atributos de instancia (únicos para cada objeto)

[Link] = nombre

[Link] = raza

[Link] = edad

[Link] = 100

def ladrar(self):

"""Método que hace ladrar al perro"""

return f"{[Link]} dice: ¡Guau!"

def correr(self, distancia):

"""Método que hace correr al perro"""

if [Link] >= distancia * 10:

[Link] -= distancia * 10

return f"{[Link]} corrió {distancia} metros"

else:
return f"{[Link]} está muy cansado para correr"

def descansar(self):

"""Método para recuperar energía"""

[Link] = 100

return f"{[Link]} descansó y recuperó toda su energía"

```

### Creación de objetos:

```python

# Crear instancias (objetos) de la clase Perro

mi_perro = Perro("Max", "Labrador", 3)

tu_perro = Perro("Luna", "Pastor Alemán", 2)

# Acceder a atributos

print(mi_perro.nombre) # "Max"

print(tu_perro.raza) # "Pastor Alemán"

# Llamar métodos

print(mi_perro.ladrar()) # "Max dice: ¡Guau!"

print(tu_perro.correr(5)) # "Luna corrió 5 metros"

```

---

## **Página 3: El método __init__ y self**

### El método constructor __init__:


```python

class CuentaBancaria:

def __init__(self, titular, saldo_inicial=0):

"""

Constructor de la clase CuentaBancaria

Args:

titular (str): Nombre del titular de la cuenta

saldo_inicial (float): Saldo inicial de la cuenta

"""

[Link] = titular

[Link] = saldo_inicial

[Link] = True

self.numero_transacciones = 0

def depositar(self, cantidad):

"""Depositar dinero en la cuenta"""

if cantidad > 0 and [Link]:

[Link] += cantidad

self.numero_transacciones += 1

return f"Depósito exitoso. Saldo actual: ${[Link]}"

return "Depósito fallido"

def retirar(self, cantidad):

"""Retirar dinero de la cuenta"""

if 0 < cantidad <= [Link] and [Link]:

[Link] -= cantidad

self.numero_transacciones += 1
return f"Retiro exitoso. Saldo actual: ${[Link]}"

return "Retiro fallido"

def consultar_saldo(self):

"""Consultar saldo actual"""

return f"Saldo de {[Link]}: ${[Link]}"

```

### Uso de self:

```python

# Crear cuentas bancarias

cuenta1 = CuentaBancaria("Ana García", 1000)

cuenta2 = CuentaBancaria("Carlos López")

# Operaciones

print([Link](500)) # "Depósito exitoso. Saldo actual: $1500"

print([Link](100)) # "Retiro fallido"

print(cuenta1.consultar_saldo()) # "Saldo de Ana García: $1500"

# Acceder a atributos

print(f"Titular: {[Link]}")

print(f"Transacciones: {cuenta1.numero_transacciones}")

```

---

## **Página 4: Encapsulación y modificadores de acceso**


### Encapsulación en Python:

Python no tiene modificadores de acceso estrictos como otros lenguajes, pero usa
convenciones:

- **Público**: `atributo` - Accesible desde cualquier lugar

- **Protegido**: `_atributo` - No debería ser accedido externamente

- **Privado**: `__atributo` - Name mangling, difícil acceso externo

### Ejemplo práctico:

```python

class CuentaSegura:

def __init__(self, titular, saldo_inicial, contraseña):

[Link] = titular # Público

self._activa = True # Protegido

self.__saldo = saldo_inicial # Privado

self.__contraseña = contraseña # Privado

# Getter para saldo

def get_saldo(self, contraseña):

"""Método para obtener el saldo de forma segura"""

if contraseña == self.__contraseña:

return self.__saldo

else:

return "Contraseña incorrecta"

# Setter para saldo

def set_saldo(self, cantidad, contraseña):

"""Método para modificar el saldo de forma segura"""


if contraseña == self.__contraseña and cantidad >= 0:

self.__saldo = cantidad

return "Saldo actualizado correctamente"

return "Error: Contraseña incorrecta o cantidad inválida"

def depositar(self, cantidad, contraseña):

"""Depositar con verificación de seguridad"""

if contraseña == self.__contraseña and cantidad > 0:

self.__saldo += cantidad

return f"Depósito exitoso. Nuevo saldo: ${self.__saldo}"

return "Depósito fallido"

```

### Uso de propiedades (@property):

```python

class Persona:

def __init__(self, nombre, edad):

[Link] = nombre

self._edad = edad # Atributo protegido

@property

def edad(self):

"""Getter para edad"""

return self._edad

@[Link]

def edad(self, valor):

"""Setter para edad con validación"""


if 0 <= valor <= 120:

self._edad = valor

else:

print("Edad no válida")

@property

def es_mayor_de_edad(self):

"""Propiedad computada"""

return self._edad >= 18

# Uso

persona = Persona("María", 25)

print([Link]) # 25

print(persona.es_mayor_de_edad) # True

[Link] = 30 # Usa el setter

[Link] = 150 # "Edad no válida"

```

---

## **Página 5: Herencia**

### Herencia básica:

```python

class Animal:

"""Clase base para todos los animales"""


def __init__(self, nombre, edad):

[Link] = nombre

[Link] = edad

def hacer_sonido(self):

return "El animal hace un sonido"

def dormir(self):

return f"{[Link]} está durmiendo"

def comer(self):

return f"{[Link]} está comiendo"

class Perro(Animal):

"""Clase Perro que hereda de Animal"""

def __init__(self, nombre, edad, raza):

# Llamar al constructor de la clase padre

super().__init__(nombre, edad)

[Link] = raza

# Sobrescribir método

def hacer_sonido(self):

return f"{[Link]} dice: ¡Guau!"

# Método específico de Perro

def mover_cola(self):

return f"{[Link]} está moviendo la cola"


class Gato(Animal):

"""Clase Gato que hereda de Animal"""

def __init__(self, nombre, edad, vidas=7):

super().__init__(nombre, edad)

[Link] = vidas

def hacer_sonido(self):

return f"{[Link]} dice: ¡Miau!"

def ronronear(self):

return f"{[Link]} está ronroneando"

```

### Uso de la herencia:

```python

# Crear objetos

mi_perro = Perro("Max", 3, "Labrador")

mi_gato = Gato("Luna", 2)

# Métodos heredados

print(mi_perro.dormir()) # "Max está durmiendo"

print(mi_gato.comer()) # "Luna está comiendo"

# Métodos sobrescritos

print(mi_perro.hacer_sonido()) # "Max dice: ¡Guau!"

print(mi_gato.hacer_sonido()) # "Luna dice: ¡Miau!"


# Métodos específicos

print(mi_perro.mover_cola()) # "Max está moviendo la cola"

print(mi_gato.ronronear()) # "Luna está ronroneando"

```

---

## **Página 6: Herencia múltiple y métodos especiales**

### Herencia múltiple:

```python

class Nadador:

def nadar(self):

return "Está nadando"

class Volador:

def volar(self):

return "Está volando"

class Corredor:

def correr(self):

return "Está corriendo"

class Pato(Nadador, Volador, Corredor):

"""Pato que puede nadar, volar y correr"""

def __init__(self, nombre):


[Link] = nombre

def hacer_todo(self):

return f"{[Link]}: {[Link]()}, {[Link]()}, {[Link]()}"

# Uso

pato = Pato("Donald")

print(pato.hacer_todo())

# "Donald: Está nadando, Está volando, Está corriendo"

```

### Métodos especiales (dunder methods):

```python

class Libro:

def __init__(self, titulo, autor, paginas):

[Link] = titulo

[Link] = autor

[Link] = paginas

# __str__ para representación legible

def __str__(self):

return f"'{[Link]}' por {[Link]}"

# __repr__ para representación técnica

def __repr__(self):

return f"Libro('{[Link]}', '{[Link]}', {[Link]})"

# __len__ para usar len(objeto)


def __len__(self):

return [Link]

# __add__ para sumar objetos

def __add__(self, otro):

return [Link] + [Link]

# __eq__ para comparación

def __eq__(self, otro):

return [Link] == [Link] and [Link] == [Link]

# Uso de métodos especiales

libro1 = Libro("1984", "George Orwell", 328)

libro2 = Libro("Rebelión en la granja", "George Orwell", 112)

print(str(libro1)) # "'1984' por George Orwell"

print(len(libro1)) # 328

print(libro1 + libro2) # 440

print(libro1 == libro2) # False

```

---

## **Página 7: Polimorfismo**

### Polimorfismo en acción:

```python

class Circulo:
def __init__(self, radio):

[Link] = radio

def area(self):

return 3.1416 * [Link] ** 2

def perimetro(self):

return 2 * 3.1416 * [Link]

class Rectangulo:

def __init__(self, ancho, alto):

[Link] = ancho

[Link] = alto

def area(self):

return [Link] * [Link]

def perimetro(self):

return 2 * ([Link] + [Link])

class Triangulo:

def __init__(self, base, altura, lado1, lado2, lado3):

[Link] = base

[Link] = altura

self.lado1 = lado1

self.lado2 = lado2

self.lado3 = lado3
def area(self):

return ([Link] * [Link]) / 2

def perimetro(self):

return self.lado1 + self.lado2 + self.lado3

# Función polimórfica

def calcular_informacion(figura):

"""Función que trabaja con cualquier figura que tenga area() y perimetro()"""

return {

'area': [Link](),

'perimetro': [Link]()

# Uso polimórfico

figuras = [

Circulo(5),

Rectangulo(4, 6),

Triangulo(3, 4, 3, 4, 5)

for figura in figuras:

info = calcular_informacion(figura)

print(f"{figura.__class__.__name__}: Área={info['area']:.2f},
Perímetro={info['perimetro']:.2f}")

```

---
## **Página 8: Clases abstractas**

### Uso de ABC (Abstract Base Classes):

```python

from abc import ABC, abstractmethod

class Forma(ABC):

"""Clase abstracta que define la interfaz para formas geométricas"""

@abstractmethod

def area(self):

"""Calcula el área de la forma"""

pass

@abstractmethod

def perimetro(self):

"""Calcula el perímetro de la forma"""

pass

# Método concreto (no abstracto)

def descripcion(self):

return "Esta es una forma geométrica"

class Cuadrado(Forma):

"""Implementación concreta de Forma"""

def __init__(self, lado):


[Link] = lado

def area(self):

return [Link] ** 2

def perimetro(self):

return 4 * [Link]

class CirculoConcreto(Forma):

"""Otra implementación concreta"""

def __init__(self, radio):

[Link] = radio

def area(self):

return 3.1416 * [Link] ** 2

def perimetro(self):

return 2 * 3.1416 * [Link]

# Uso

cuadrado = Cuadrado(5)

circulo = CirculoConcreto(3)

print(f"Cuadrado - Área: {[Link]()}, Perímetro: {[Link]()}")

print(f"Círculo - Área: {[Link]():.2f}, Perímetro: {[Link]():.2f}")

```
---

## **Página 9: Métodos de clase y estáticos**

### Métodos de clase (@classmethod):

```python

class Persona:

contador_personas = 0 # Variable de clase

def __init__(self, nombre, edad):

[Link] = nombre

[Link] = edad

Persona.contador_personas += 1

@classmethod

def get_total_personas(cls):

"""Método de clase - trabaja con la clase, no con la instancia"""

return cls.contador_personas

@classmethod

def crear_desde_string(cls, cadena):

"""Método de clase alternativo para crear instancias"""

nombre, edad = [Link]('-')

return cls(nombre, int(edad))

class Estudiante(Persona):

contador_estudiantes = 0
def __init__(self, nombre, edad, carrera):

super().__init__(nombre, edad)

[Link] = carrera

Estudiante.contador_estudiantes += 1

@classmethod

def get_total_estudiantes(cls):

return cls.contador_estudiantes

```

### Métodos estáticos (@staticmethod):

```python

class Calculadora:

@staticmethod

def sumar(a, b):

"""Método estático - no necesita self ni cls"""

return a + b

@staticmethod

def es_par(numero):

"""Verifica si un número es par"""

return numero % 2 == 0

@staticmethod

def calcular_imc(peso, altura):

"""Calcula el Índice de Masa Corporal"""

return peso / (altura ** 2)

```
### Uso:

```python

# Métodos de clase

persona1 = Persona("Ana", 25)

persona2 = Persona.crear_desde_string("Carlos-30")

print(Persona.get_total_personas()) # 2

estudiante = Estudiante("María", 20, "Ingeniería")

print(Estudiante.get_total_estudiantes()) # 1

# Métodos estáticos

print([Link](5, 3)) #8

print(Calculadora.es_par(10)) # True

print(f"IMC: {Calculadora.calcular_imc(70, 1.75):.2f}")

```

---

## **Página 10: Proyecto - Sistema de vehículos**

```python

class Vehiculo:

"""Clase base para todos los vehículos"""

def __init__(self, marca, modelo, año, color):

[Link] = marca
[Link] = modelo

self.año = año

[Link] = color

[Link] = 0

[Link] = False

def encender(self):

if not [Link]:

[Link] = True

return f"{[Link]} {[Link]} encendido"

return "El vehículo ya está encendido"

def apagar(self):

if [Link] and [Link] == 0:

[Link] = False

return f"{[Link]} {[Link]} apagado"

return "No se puede apagar en movimiento"

def acelerar(self, incremento):

if [Link]:

[Link] += incremento

return f"Velocidad: {[Link]} km/h"

return "Primero debe encender el vehículo"

def frenar(self, decremento):

if [Link] > 0:

[Link] = max(0, [Link] - decremento)

return f"Velocidad: {[Link]} km/h"


return "El vehículo ya está detenido"

def __str__(self):

return f"{self.año} {[Link]} {[Link]} - {[Link]}"

class Coche(Vehiculo):

def __init__(self, marca, modelo, año, color, num_puertas, tipo_combustible):

super().__init__(marca, modelo, año, color)

self.num_puertas = num_puertas

self.tipo_combustible = tipo_combustible

self.nivel_combustible = 100

def repostar(self, cantidad):

self.nivel_combustible = min(100, self.nivel_combustible + cantidad)

return f"Nivel de combustible: {self.nivel_combustible}%"

def acelerar(self, incremento):

if self.nivel_combustible > 0:

resultado = super().acelerar(incremento)

self.nivel_combustible -= incremento * 0.1

return resultado

return "Sin combustible"

class Motocicleta(Vehiculo):

def __init__(self, marca, modelo, año, color, cilindrada):

super().__init__(marca, modelo, año, color)

[Link] = cilindrada

self.maniobra_riesgo = False
def hacer_caballito(self):

if [Link] and [Link] > 20:

self.maniobra_riesgo = True

return "¡Haciendo caballito!"

return "No se puede hacer caballito"

def acelerar(self, incremento):

# Las motos aceleran más rápido

resultado = super().acelerar(incremento * 1.5)

return [Link]("km/h", "km/h (moto)")

class Camion(Vehiculo):

def __init__(self, marca, modelo, año, color, capacidad_carga):

super().__init__(marca, modelo, año, color)

self.capacidad_carga = capacidad_carga

self.carga_actual = 0

def cargar(self, peso):

if self.carga_actual + peso <= self.capacidad_carga:

self.carga_actual += peso

return f"Carga actual: {self.carga_actual}/{self.capacidad_carga} kg"

return "Excede la capacidad máxima"

def acelerar(self, incremento):

# Los camiones aceleran más lento con carga

factor_carga = max(0.5, 1 - (self.carga_actual / self.capacidad_carga) * 0.5)

resultado = super().acelerar(incremento * factor_carga)


return [Link]("km/h", "km/h (camión)")

# Demo del sistema

if __name__ == "__main__":

# Crear vehículos

mi_coche = Coche("Toyota", "Corolla", 2022, "Rojo", 4, "Gasolina")

mi_moto = Motocicleta("Yamaha", "MT-07", 2023, "Azul", 689)

mi_camion = Camion("Volvo", "FH", 2020, "Blanco", 20000)

# Probar funcionalidades

vehiculos = [mi_coche, mi_moto, mi_camion]

for vehiculo in vehiculos:

print(f"\n=== Probando {vehiculo.__class__.__name__} ===")

print([Link]())

print([Link](30))

# Comportamientos específicos

if isinstance(vehiculo, Coche):

print([Link](20))

elif isinstance(vehiculo, Motocicleta):

print(vehiculo.hacer_caballito())

elif isinstance(vehiculo, Camion):

print([Link](5000))

print([Link](30))

print([Link]())

```
---

## **Página 11: Ejercicios prácticos**

### Ejercicio 1: Sistema de empleados

```python

class Empleado:

def __init__(self, nombre, salario_base, departamento):

[Link] = nombre

self.salario_base = salario_base

[Link] = departamento

self._activo = True

def calcular_salario(self):

return self.salario_base

def despedir(self):

self._activo = False

return f"{[Link]} ha sido despedido/a"

def __str__(self):

estado = "Activo" if self._activo else "Inactivo"

return f"{[Link]} - {[Link]} - {estado}"

class Gerente(Empleado):

def __init__(self, nombre, salario_base, departamento, bono):

super().__init__(nombre, salario_base, departamento)


[Link] = bono

self.empleados_a_cargo = []

def agregar_empleado(self, empleado):

self.empleados_a_cargo.append(empleado)

def calcular_salario(self):

return self.salario_base + [Link] + (len(self.empleados_a_cargo) * 100)

def listar_empleados(self):

return [[Link] for emp in self.empleados_a_cargo]

class Desarrollador(Empleado):

def __init__(self, nombre, salario_base, departamento, lenguaje):

super().__init__(nombre, salario_base, departamento)

[Link] = lenguaje

self.proyectos_completados = 0

def completar_proyecto(self):

self.proyectos_completados += 1

def calcular_salario(self):

return self.salario_base + (self.proyectos_completados * 50)

# Uso del sistema

gerente = Gerente("Ana García", 50000, "TI", 10000)

dev1 = Desarrollador("Carlos López", 40000, "TI", "Python")

dev2 = Desarrollador("María Rodríguez", 42000, "TI", "JavaScript")


gerente.agregar_empleado(dev1)

gerente.agregar_empleado(dev2)

dev1.completar_proyecto()

dev1.completar_proyecto()

dev2.completar_proyecto()

empleados = [gerente, dev1, dev2]

for emp in empleados:

print(f"{emp} - Salario: ${emp.calcular_salario():,}")

print(f"Empleados a cargo de {[Link]}: {gerente.listar_empleados()}")

```

---

## **Página 12: Resumen del capítulo**

### Conceptos aprendidos:

- Clases y objetos (instanciación)

- Método __init__ y self

- Encapsulación y modificadores de acceso

- Herencia simple y múltiple

- Polimorfismo y métodos abstractos

- Métodos especiales (__str__, __len__, etc.)

- Métodos de clase (@classmethod) y estáticos (@staticmethod)


- Propiedades (@property)

### Pilares de la POO dominados:

1. **Encapsulación**: Ocultar detalles con _ y __

2. **Herencia**: Crear jerarquías de clases

3. **Polimorfismo**: Mismo interfaz, diferentes comportamientos

4. **Abstracción**: ABC y métodos abstractos

También podría gustarte