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.
Clases y Objetos
Un molde (clase) y sus instancias (objetos). El bloque fundamental de la POO.
Encapsulamiento
Ocultar el estado interno y exponer solo lo necesario mediante una interfaz.
Herencia
Una clase reutiliza y extiende el comportamiento de otra ya existente.
Polimorfismo
El mismo mensaje produce comportamientos distintos según el objeto real.
Clases y Objetos
| Término | Significado |
|---|---|
| Clase | Plantilla que define atributos y métodos |
| Objeto | Instancia concreta de una clase en memoria |
| Atributo | Variable miembro — el estado del objeto |
| Método | Función miembro — el comportamiento |
| this | Puntero 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; }
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.
Encapsulamiento
| Modificador | Visible desde |
|---|---|
| private | Solo dentro de la misma clase |
| protected | La clase y sus clases derivadas |
| public | Desde cualquier parte del programa |
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; } };
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.
Constructores y Destructores
| Tipo | Cuándo se usa |
|---|---|
| Por defecto | Animal() — sin parámetros |
| Parametrizado | Animal(string, int) — inicializa con valores |
| Copia | Animal(const Animal&) — clona otro objeto |
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"; } };
Herencia
| public | protected | private |
|---|---|---|
| Miembros public siguen public | Miembros public pasan a protected | Miembros 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 }
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.
Polimorfismo
| Palabra | Rol |
|---|---|
| virtual | En la clase base, habilita el despacho dinámico |
| override | En 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! }
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.
Abstracción
Una clase con al menos un método virtual puro no puede instanciarse directamente. Solo define el contrato que las clases derivadas deben cumplir.
| Concepto | Detalle |
|---|---|
| = 0 | Marca un método como virtual puro |
| Clase abstracta | No se puede hacer new Forma() |
| Clase concreta | Implementa 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; } };
Los 4 pilares — comparativa
| Pilar | Encapsulamiento | Herencia | Polimorfismo |
|---|---|---|---|
| Objetivo | Ocultar el estado interno | Reutilizar comportamiento | Responder distinto al mismo mensaje |
| Palabra clave | private / public | : public Base | virtual / override |
| Se usa cuando | Hay datos que deben protegerse | Existe relación "es-un" | Hay múltiples formas de un mismo comportamiento |
| Riesgo si se abusa | Getters/setters innecesarios | Jerarquías muy profundas y rígidas | Overhead de tabla virtual |
| Herencia ("es-un") | Composición ("tiene-un") | |
|---|---|---|
| Relación | Perro : public Animal | class Auto { Motor motor; } |
| Acoplamiento | Alto — cambia la clase base, cambia todo | Bajo — se puede cambiar la pieza interna |
| Flexibilidad | Fija en tiempo de compilación | Se puede intercambiar en tiempo de ejecución |
Ejercicios propuestos
Clase Libro
Crea una clase Libro con atributos titulo, autor y paginas. Agrega un método resumen() que imprima los datos.
: titulo(t), autor(a)Cuenta con validación
Agrega a CuentaBancaria un método transferir(CuentaBancaria& otra, double monto) que valide fondos antes de mover el dinero.
retirar() y depositar() internamente.Empleados
Crea Empleado con calcularSueldo(). Deriva Gerente (sueldo + bono) y Vendedor (sueldo + comisión).
: Empleado(nombre, sueldoBase).Formas geométricas
Define Forma abstracta con area() virtual puro. Implementa Circulo, Rectangulo y Triangulo. Suma el área total de un vector<Forma*>.
Sistema de notificaciones
Crea una interfaz Notificador con enviar(string msg) virtual puro. Implementa EmailNotificador y SMSNotificador.
enviar() a través de un puntero a la clase base.Jerarquía de vehículos
Diseña Vehiculo → Auto, Motocicleta, Camion, cada uno con capacidadCarga() distinta.
protected vs private.Cierre
La POO es la forma en que casi todo el software moderno organiza su complejidad.
Clases → Encapsulamiento → Herencia → Polimorfismo → Abstracción