Programación Orientada a Objetos · C++11

Clases·Objetos
Herencia·Polimorfismo

Modelar el mundo real en código: entidades con datos y comportamiento propio, que se relacionan, se especializan y responden de forma distinta ante el mismo mensaje.

C++11 o superior
📋 Prereq: funciones, structs, punteros básicos
🧠 class · virtual · public/private
BASE

Clases y Objetos

Un molde (clase) y sus instancias (objetos). El bloque fundamental de la POO.

class Animal { ... };
PILAR

Encapsulamiento

Ocultar el estado interno y exponer solo lo necesario mediante una interfaz.

private · public · protected
PILAR

Herencia

Una clase reutiliza y extiende el comportamiento de otra ya existente.

class Perro : public Animal
PILAR

Polimorfismo

El mismo mensaje produce comportamientos distintos según el objeto real.

virtual void sonido();
scroll
BLOQUE 01

Clases y Objetos

🔑 FUNDAMENTO — Sin clases no hay POO
la clase como molde — los objetos como instancias
class Animal
Atributos
string nombre; int edad;
Métodos
comer(); dormir(); sonido();
↓ se instancian ↓
rexAnimal rex("Rex", 3)
miauAnimal miau("Miau", 1)
tobyAnimal toby("Toby", 5)
Términos esenciales
TérminoSignificado
ClasePlantilla que define atributos y métodos
ObjetoInstancia concreta de una clase en memoria
AtributoVariable miembro — el estado del objeto
MétodoFunción miembro — el comportamiento
thisPuntero implícito al objeto actual
// ===== Definición de la clase =====
class Animal {
private:
    std::string nombre;
    int edad;

public:
    // Constructor
    Animal(std::string n, int e)
        : nombre(n), edad(e) {}

    void comer() {
        std::cout << nombre << " está comiendo";
    }

    std::string getNombre() const {
        return nombre;
    }
};

// ===== Creación de objetos (instancias) =====
int main() {
    Animal rex("Rex", 3);   // objeto en stack
    rex.comer();

    Animal* p = new Animal("Miau", 1); // en heap
    p->comer();
    delete p;
}
¿Por qué agrupar datos y comportamiento?
🧩

Modelar el mundo real

Un Cliente, una CuentaBancaria, un Vehiculo — cada entidad con sus propios datos y acciones.

🔁

Reutilización

Una vez definida la clase, se crean tantos objetos como se necesiten sin repetir código.

🧱

Organización

El código crece en módulos con responsabilidad propia, más fácil de mantener y probar.

BLOQUE 02

Encapsulamiento

🔒 PILAR 1 — Ocultar el estado, exponer la interfaz
Niveles de acceso
ModificadorVisible desde
privateSolo dentro de la misma clase
protectedLa clase y sus clases derivadas
publicDesde cualquier parte del programa
Regla práctica: los atributos casi siempre private, y se accede a ellos mediante métodos get/set públicos que pueden validar el dato.
class CuentaBancaria {
private:
    double saldo;  // nadie accede directo

public:
    CuentaBancaria(double inicial) : saldo(inicial) {}

    // setter con validación
    void depositar(double monto) {
        if (monto > 0) saldo += monto;
    }

    bool retirar(double monto) {
        if (monto <= 0 || monto > saldo)
            return false;  // invariante protegido
        saldo -= monto;
        return true;
    }

    // getter de solo lectura
    double getSaldo() const { return saldo; }
};
Casos de uso reales
💳

Cuentas bancarias

El saldo nunca se modifica directo — siempre pasa por reglas de negocio (retirar, depositar).

🎮

Vida de un personaje

La salud es privada; solo recibirDaño() o curar() pueden modificarla, evitando valores inválidos.

🔐

Formularios y validación

Un setter de email puede rechazar formatos inválidos antes de guardarlos.

BLOQUE 03

Constructores y Destructores

⚡ CICLO DE VIDA — Nacimiento y muerte de un objeto
Tipos de constructor
TipoCuándo se usa
Por defectoAnimal() — sin parámetros
ParametrizadoAnimal(string, int) — inicializa con valores
CopiaAnimal(const Animal&) — clona otro objeto
Destructor

Se ejecuta automáticamente cuando el objeto sale de alcance o se hace delete. Ideal para liberar memoria dinámica u otros recursos.

class Mascota {
private:
    std::string nombre;
    int* edad;  // recurso dinámico

public:
    // Constructor por defecto
    Mascota() : nombre("Sin nombre"), edad(new int(0)) {
        std::cout << "Constructor por defecto\n";
    }

    // Constructor parametrizado
    Mascota(std::string n, int e)
        : nombre(n), edad(new int(e)) {
        std::cout << "Constructor parametrizado\n";
    }

    // Destructor — libera el recurso
    ~Mascota() {
        delete edad;
        std::cout << nombre << " destruida\n";
    }
};
BLOQUE 04

Herencia

🌳 PILAR 2 — Reutilizar y especializar comportamiento
jerarquía de clases
Animal
Perro
Gato
Ave
Tipos de herencia (según acceso)
publicprotectedprivate
Miembros public siguen publicMiembros public pasan a protectedMiembros public pasan a private

En la práctica, casi siempre se usa public — es la relación "es-un" (Perro es-un Animal).

class Animal {
protected:
    std::string nombre;
public:
    Animal(std::string n) : nombre(n) {}
    void dormir() { std::cout << nombre << " duerme\n"; }
    virtual void sonido() { std::cout << "..."; }
};

// Perro HEREDA de Animal — es-un Animal
class Perro : public Animal {
public:
    Perro(std::string n) : Animal(n) {}  // llama al ctor base

    // Sobrescribe (override) el comportamiento
    void sonido() override {
        std::cout << nombre << " dice: Guau!\n";
    }

    // Método nuevo, exclusivo de Perro
    void buscarPelota() {
        std::cout << nombre << " busca la pelota\n";
    }
};

int main() {
    Perro rex("Rex");
    rex.dormir();       // heredado de Animal
    rex.sonido();       // sobrescrito por Perro
    rex.buscarPelota(); // propio de Perro
}
Casos de uso reales
🚗

Vehículos

Auto, Moto y Camion heredan de Vehiculo el atributo velocidad y el método acelerar().

🖼️

Componentes de UI

Boton, Checkbox e Input heredan de Widget la posición y el método render().

👥

Tipos de empleado

Gerente y Vendedor heredan de Empleado, cada uno calcula su sueldo distinto.

BLOQUE 05

Polimorfismo

🎭 PILAR 3 — Mismo mensaje, respuesta distinta
demo interactiva — despacho virtual
>animal->sonido();
Por qué funciona: virtual + override
PalabraRol
virtualEn la clase base, habilita el despacho dinámico
overrideEn la derivada, confirma que reemplaza el método base
Animal*Un puntero a base puede apuntar a cualquier derivada
class Animal {
public:
    virtual void sonido() { std::cout << "..."; }
    virtual ~Animal() {}  // destructor virtual ★
};

class Perro : public Animal {
public:
    void sonido() override { std::cout << "Guau!"; }
};

class Gato : public Animal {
public:
    void sonido() override { std::cout << "Miau!"; }
};

// ===== El mismo código, distinto resultado =====
void hacerSonar(Animal* a) {
    a->sonido();  // decide en tiempo de EJECUCIÓN
}

int main() {
    Animal* lista[] = {
        new Perro(), new Gato()
    };
    for (auto a : lista) hacerSonar(a); // Guau! Miau!
}
Casos de uso reales
🖌️

Motores gráficos

Un vector de Forma* contiene círculos y rectángulos; cada uno sabe dibujar() a su manera.

💰

Métodos de pago

Tarjeta, Efectivo y Transferencia implementan procesar() de forma distinta tras la misma interfaz.

🕹️

Enemigos de un juego

Todos responden a atacar(), pero cada tipo de enemigo ejecuta su propia estrategia.

BLOQUE 06

Abstracción

🧊 PILAR 4 — Definir el "qué" sin el "cómo"
Clase abstracta

Una clase con al menos un método virtual puro no puede instanciarse directamente. Solo define el contrato que las clases derivadas deben cumplir.

ConceptoDetalle
= 0Marca un método como virtual puro
Clase abstractaNo se puede hacer new Forma()
Clase concretaImplementa todos los métodos puros heredados
// Clase abstracta — define el contrato
class Forma {
public:
    virtual double area() const = 0;  // virtual puro
    virtual ~Forma() {}
};

// Forma NO se puede instanciar:
// Forma f; ← error de compilación

class Circulo : public Forma {
    double radio;
public:
    Circulo(double r) : radio(r) {}
    double area() const override {
        return 3.14159 * radio * radio;
    }
};
BLOQUE 07

Los 4 pilares — comparativa

PilarEncapsulamientoHerenciaPolimorfismo
ObjetivoOcultar el estado internoReutilizar comportamientoResponder distinto al mismo mensaje
Palabra claveprivate / public: public Basevirtual / override
Se usa cuandoHay datos que deben protegerseExiste relación "es-un"Hay múltiples formas de un mismo comportamiento
Riesgo si se abusaGetters/setters innecesariosJerarquías muy profundas y rígidasOverhead de tabla virtual
Herencia vs. Composición
Herencia ("es-un")Composición ("tiene-un")
RelaciónPerro : public Animalclass Auto { Motor motor; }
AcoplamientoAlto — cambia la clase base, cambia todoBajo — se puede cambiar la pieza interna
FlexibilidadFija en tiempo de compilaciónSe puede intercambiar en tiempo de ejecución
BLOQUE 08

Ejercicios propuestos

EJ-01CLASES

Clase Libro

Crea una clase Libro con atributos titulo, autor y paginas. Agrega un método resumen() que imprima los datos.

💡 Usa una lista de constructor: : titulo(t), autor(a)
EJ-02ENCAPS.

Cuenta con validación

Agrega a CuentaBancaria un método transferir(CuentaBancaria& otra, double monto) que valide fondos antes de mover el dinero.

💡 Reutiliza retirar() y depositar() internamente.
EJ-03HERENCIA

Empleados

Crea Empleado con calcularSueldo(). Deriva Gerente (sueldo + bono) y Vendedor (sueldo + comisión).

💡 Llama al constructor de la base con : Empleado(nombre, sueldoBase).
EJ-04POLIMORF.

Formas geométricas

Define Forma abstracta con area() virtual puro. Implementa Circulo, Rectangulo y Triangulo. Suma el área total de un vector<Forma*>.

💡 No olvides el destructor virtual en la clase base.
EJ-05POLIMORF.

Sistema de notificaciones

Crea una interfaz Notificador con enviar(string msg) virtual puro. Implementa EmailNotificador y SMSNotificador.

💡 Prueba llamando enviar() a través de un puntero a la clase base.
EJ-06HERENCIA

Jerarquía de vehículos

Diseña VehiculoAuto, Motocicleta, Camion, cada uno con capacidadCarga() distinta.

💡 Piensa qué atributos son protected vs private.
BLOQUE 09

Cierre

La POO es la forma en que casi todo el software moderno organiza su complejidad.

Clases → Encapsulamiento → Herencia → Polimorfismo → Abstracción

"¿Cómo modelo una entidad del mundo real?"
Una clase con atributos y métodos
"¿Cómo protejo el estado interno?"
private + getters/setters
"¿Cómo reutilizo comportamiento?"
Herencia — class B : public A
"¿Cómo respondo distinto al mismo mensaje?"
virtual + override
Lo que se construye sobre lo visto hoy
Clases →
Structs avanzados · Templates · STL containers
Herencia →
Interfaces · Mixins · Diamond problem
Polimorfismo →
Patrones de diseño · Inyección de dependencias
Abstracción →
Arquitectura de software · SOLID