Skip to content

📘 Clase 6 — Clases (POO básica)

TypeScript · 2026-07-12 · Carpeta: 02-Ejercicios/Clases ⬅️ Volver al índice de clases

🎯 Qué aprendí

  • Qué es una clase en TypeScript y para qué se usa.
  • La diferencia entre una clase y una interface.
  • Cómo declarar propiedades dentro de una clase.
  • Cómo construir objetos con constructor.
  • Por qué se usa this para guardar los valores en la instancia.
  • Cómo exportar una clase e importarla desde otro archivo.
  • La convención de un archivo, una clase.

📖 PARTE TEÓRICA

🧱 1. ¿Qué son las clases en TypeScript?

Las clases en TypeScript son la columna vertebral de la programación orientada a objetos. Permiten agrupar propiedades, constructor y métodos en una sola estructura para crear objetos reutilizables.

Además, te ayudan a organizar el proyecto para que una clase viva en su propio archivo y pueda ser reutilizada desde otros módulos.

💡 Idea clave: una clase no solo describe la forma de un objeto, también define su comportamiento.

⚖️ 2. Diferencia entre clase e interface

Visualmente se parecen, pero no cumplen el mismo papel.

Una interface describe cómo debe verse un objeto. Una clase sí crea objetos con lógica propia: propiedades, constructor y métodos.

interfaceclass
Describe estructura
Tiene constructor
Tiene métodos con lógica
Se instancia con new
Existe en el JS final
typescript
interface PersonaI {
  nombre: string;
}

class Persona {
  nombre: string;

  constructor(nombre: string) {
    this.nombre = nombre;
  }
}

🧪 ¿Cuándo uso una clase en lugar de una interface? Cuando necesitas crear objetos con lógica propia (métodos), no solo describir su forma.

👤 3. Crear una clase Persona

En este tema, la clase real trabajada fue esta:

typescript
export class Persona {
  nombre: string;
  edad: number;
  esDesarrollador: boolean;

  constructor(nombre: string, edad: number, esDesarrollador: boolean) {
    this.nombre = nombre;
    this.edad = edad;
    this.esDesarrollador = esDesarrollador;
  }

  saludar(): string {
    return `Hola, mi nombre es ${this.nombre}, tengo ${this.edad} años y ${this.esDesarrollador ? "soy desarrollador" : "no soy desarrollador"}.`;
  }
}

Aquí hay tres partes importantes:

  • Propiedades: nombre, edad, esDesarrollador
  • Constructor: recibe los datos al crear el objeto
  • Método: saludar() devuelve un texto usando los datos internos

🏗️ 4. ¿Qué hace el constructor?

El constructor es una función especial que se ejecuta automáticamente al crear el objeto con new.

typescript
constructor(nombre: string, edad: number, esDesarrollador: boolean) {
  this.nombre = nombre;
  this.edad = edad;
  this.esDesarrollador = esDesarrollador;
}

Su trabajo es tomar los datos que entran y guardarlos dentro del objeto.

typescript
let persona = new Persona("Styp", 30, true);

En ese momento:

  • "Styp" se guarda en this.nombre
  • 30 se guarda en this.edad
  • true se guarda en this.esDesarrollador

💡 El constructor es como la "fase de armado" inicial del objeto.

🪞 5. ¿Por qué se usa this?

Dentro del constructor conviven dos nombres parecidos:

  • el parámetro que entra
  • la propiedad del objeto

Por eso escribimos:

typescript
this.nombre = nombre;

Eso significa:

  • this.nombre → la propiedad de la clase
  • nombre → el valor recibido como parámetro

Si no usas this, no estarías guardando nada dentro del objeto.

🧪 Lectura mental correcta: this.nombre = nombre significa "guarda el valor recibido en la propiedad nombre del objeto actual".

🗣️ 6. Métodos de una clase

Un método es una función que pertenece al objeto.

typescript
saludar(): string {
  return `Hola, mi nombre es ${this.nombre}, tengo ${this.edad} años y ${this.esDesarrollador ? "soy desarrollador" : "no soy desarrollador"}.`;
}

Este método no necesita parámetros porque usa directamente los datos ya guardados en la instancia mediante this.

typescript
console.log(persona.saludar());

📌 Una clase sirve justo para eso: guardar datos y exponer acciones relacionadas con esos datos.

📦 7. Exportar e importar una clase

Para que una clase pueda usarse en otros archivos, debe exportarse:

typescript
export class Persona {
  // ...
}

Luego, en otro archivo, la importas:

typescript
import { Persona } from "./clase.js";

Y recién ahí la puedes usar:

typescript
let persona = new Persona("Styp", 30, true);
console.log(persona.saludar());

💡 export marca la clase como accesible desde otros archivos. Sin export, TypeScript no te dejará importarla.

🧩 8. Separar la clase del archivo de implementación

Aunque puedes poner todo en un mismo archivo, no es buena práctica cuando el proyecto crece.

En este tema se separó así:

  • clase.ts → contiene la definición de Persona
  • implementacion.ts → importa Persona, crea la instancia y la usa

Eso hace que la clase sea agnóstica al archivo donde se consume.

💡 La clase debe ser reutilizable. Si mañana quieres usar Persona en otro archivo, solo la importas. No necesitas copiar nada.

📁 9. Principio: un archivo, una clase

Esta convención mantiene el proyecto ordenado:

  • cada clase vive en su propio archivo
  • se importa donde haga falta
  • no se duplica código
  • se reducen dependencias raras

🧪 ¿Por qué separar la clase del archivo de implementación? Porque la clase debe poder reutilizarse en muchos archivos distintos sin quedar pegada a un único caso de uso.


💻 PARTE PRÁCTICA

Archivos trabajados:

  • 02-Ejercicios/Clases/clase.ts
  • 02-Ejercicios/Clases/implementacion.ts
bash
cd 02-Ejercicios/Clases
tsc && node implementacion.js

Código verificado:

  • clase.ts exporta la clase Persona
  • implementacion.ts la importa con ./clase.js
  • se crea una instancia con new Persona("Styp", 30, true)
  • se llama al método saludar()

Salida real:

text
Hola, mi nombre es Styp, tengo 30 años y soy desarrollador.

Todo verificado y corriendo. ✅


🏋️ EJERCICIOS CON SOLUCIÓN

Ejercicio 1 — Clase Producto

Crea una clase Producto con nombre y precio. Agrega un método mostrarInfo() que devuelva una cadena con esos datos.

Ver solución
typescript
export class Producto {
  nombre: string;
  precio: number;

  constructor(nombre: string, precio: number) {
    this.nombre = nombre;
    this.precio = precio;
  }

  mostrarInfo(): string {
    return `Producto: ${this.nombre}, Precio: ${this.precio}`;
  }
}

let producto = new Producto("Mouse", 45);
console.log(producto.mostrarInfo());

Terminal esperada:

zsh · producto.ts
$ tsc producto.ts
$ node producto.js
Producto: Mouse, Precio: 45

Ejercicio 2 — Clase Estudiante

Crea una clase Estudiante con nombre y nota. Agrega un método aprobo() que devuelva true si la nota es mayor o igual a 11.

Ver solución
typescript
class Estudiante {
  nombre: string;
  nota: number;

  constructor(nombre: string, nota: number) {
    this.nombre = nombre;
    this.nota = nota;
  }

  aprobo(): boolean {
    return this.nota >= 11;
  }
}

let estudiante = new Estudiante("Lucía", 15);
console.log(estudiante.aprobo()); // true

Terminal esperada:

zsh · estudiante.ts
$ tsc estudiante.ts
$ node estudiante.js
true

Ejercicio 3 — Clase con varios métodos

Crea una clase CuentaBancaria con titular y saldo. Agrega dos métodos: depositar(monto) y retirar(monto).

Ver solución
typescript
class CuentaBancaria {
  titular: string;
  saldo: number;

  constructor(titular: string, saldo: number) {
    this.titular = titular;
    this.saldo = saldo;
  }

  depositar(monto: number): void {
    this.saldo += monto;
  }

  retirar(monto: number): void {
    this.saldo -= monto;
  }
}

let cuenta = new CuentaBancaria("Ana", 1000);
cuenta.depositar(200);
cuenta.retirar(150);
console.log(cuenta.saldo); // 1050

Terminal esperada:

zsh · cuentaBancaria.ts
$ tsc cuentaBancaria.ts
$ node cuentaBancaria.js
1050

Ejercicio 4 — Clase separada en archivos

Crea una clase Animal en un archivo y luego impórtala desde otro archivo para instanciarla y llamar un método hablar().

Ver solución
typescript
// animal.ts
export class Animal {
  nombre: string;

  constructor(nombre: string) {
    this.nombre = nombre;
  }

  hablar(): string {
    return `${this.nombre} está haciendo un sonido.`;
  }
}

// uso.ts
import { Animal } from "./animal.js";

let animal = new Animal("Perro");
console.log(animal.hablar());

Terminal esperada:

zsh · uso.ts
$ tsc uso.ts
$ node uso.js
Perro está haciendo un sonido.

Ejercicio 5 — Clase Inventario con búsqueda

Crea una clase Inventario que guarde una lista de productos. Debe tener:

  • una propiedad productos
  • un método agregarProducto()
  • un método buscarPorNombre() que devuelva el producto encontrado o undefined
Ver solución
typescript
class Producto {
  nombre: string;
  precio: number;

  constructor(nombre: string, precio: number) {
    this.nombre = nombre;
    this.precio = precio;
  }
}

class Inventario {
  productos: Producto[];

  constructor() {
    this.productos = [];
  }

  agregarProducto(producto: Producto): void {
    this.productos.push(producto);
  }

  buscarPorNombre(nombre: string): Producto | undefined {
    return this.productos.find((producto) => producto.nombre === nombre);
  }
}

let inventario = new Inventario();
inventario.agregarProducto(new Producto("Teclado", 120));
inventario.agregarProducto(new Producto("Mouse", 45));

let encontrado = inventario.buscarPorNombre("Mouse");
console.log(encontrado);

Terminal esperada:

zsh · inventario.ts
$ tsc inventario.ts
$ node inventario.js
Producto { nombre: 'Mouse', precio: 45 }

Ejercicio 6 — Clase CarritoCompras con cálculo total

Crea una clase CarritoCompras que reciba productos y tenga un método calcularTotal(). Además, agrega un método mostrarResumen() que imprima cada producto y el total final.

Ver solución
typescript
class Producto {
  nombre: string;
  precio: number;

  constructor(nombre: string, precio: number) {
    this.nombre = nombre;
    this.precio = precio;
  }
}

class CarritoCompras {
  productos: Producto[];

  constructor() {
    this.productos = [];
  }

  agregarProducto(producto: Producto): void {
    this.productos.push(producto);
  }

  calcularTotal(): number {
    return this.productos.reduce((acc, producto) => acc + producto.precio, 0);
  }

  mostrarResumen(): void {
    this.productos.forEach((producto) => {
      console.log(`Producto: ${producto.nombre} - Precio: ${producto.precio}`);
    });

    console.log(`Total: ${this.calcularTotal()}`);
  }
}

let carrito = new CarritoCompras();
carrito.agregarProducto(new Producto("Laptop", 3500));
carrito.agregarProducto(new Producto("Mouse", 80));
carrito.agregarProducto(new Producto("Audífonos", 150));

carrito.mostrarResumen();

Terminal esperada:

zsh · carrito.ts
$ tsc carrito.ts
$ node carrito.js
Producto: Laptop - Precio: 3500
Producto: Mouse - Precio: 80
Producto: Audífonos - Precio: 150
Total: 3730

Ejercicio 7 — Clase Biblioteca con préstamo de libros

Crea una clase Libro con titulo, autor y disponible. Luego crea una clase Biblioteca con métodos para:

  • agregar libros
  • prestar un libro por título
  • mostrar los libros disponibles

Cuando un libro se presta, su propiedad disponible debe cambiar a false.

Ver solución
typescript
class Libro {
  titulo: string;
  autor: string;
  disponible: boolean;

  constructor(titulo: string, autor: string, disponible: boolean = true) {
    this.titulo = titulo;
    this.autor = autor;
    this.disponible = disponible;
  }
}

class Biblioteca {
  libros: Libro[];

  constructor() {
    this.libros = [];
  }

  agregarLibro(libro: Libro): void {
    this.libros.push(libro);
  }

  prestarLibro(titulo: string): void {
    let libro = this.libros.find((libroActual) => libroActual.titulo === titulo);

    if (libro && libro.disponible) {
      libro.disponible = false;
      console.log(`Prestaste el libro: ${libro.titulo}`);
    } else {
      console.log("Libro no disponible.");
    }
  }

  mostrarDisponibles(): void {
    this.libros
      .filter((libro) => libro.disponible)
      .forEach((libro) => {
        console.log(`Disponible: ${libro.titulo} - ${libro.autor}`);
      });
  }
}

let biblioteca = new Biblioteca();
biblioteca.agregarLibro(new Libro("Clean Code", "Robert C. Martin"));
biblioteca.agregarLibro(new Libro("TypeScript Deep Dive", "Basarat"));
biblioteca.agregarLibro(new Libro("Refactoring", "Martin Fowler"));

biblioteca.prestarLibro("Clean Code");
biblioteca.mostrarDisponibles();

Terminal esperada:

zsh · biblioteca.ts
$ tsc biblioteca.ts
$ node biblioteca.js
Prestaste el libro: Clean Code
Disponible: TypeScript Deep Dive - Basarat
Disponible: Refactoring - Martin Fowler

🧭 ¿Para qué se usan las clases?

Las clases se usan cuando un dato no solo necesita forma, sino también comportamiento.

  • Para modelar entidades como Persona, Producto, CuentaBancaria, Empleado o Animal.
  • Para agrupar propiedades y métodos relacionados en una sola estructura.
  • Para crear múltiples objetos a partir de una misma plantilla usando new.
  • Para organizar mejor el proyecto separando definición e implementación.
  • Para reutilizar lógica sin copiar código entre archivos.
  • Como base de la programación orientada a objetos: más adelante sirven para herencia, encapsulamiento y composición.

💡 En resumen: usa clases cuando necesites objetos "vivos", con datos y acciones propias.


❓ Preguntas y respuestas (autoevaluación)

1. ¿Qué es una clase en TypeScript?

Una estructura que agrupa propiedades, constructor y métodos para crear objetos reutilizables.

2. ¿Cuál es la diferencia principal entre clase e interface?

La interface describe forma; la clase describe forma y además implementa lógica.

3. ¿Para qué sirve el constructor?

Para inicializar el objeto con los datos que recibe al momento de crearlo con new.

4. ¿Qué significa this.nombre = nombre?

Guarda el valor del parámetro nombre dentro de la propiedad nombre del objeto actual.

5. ¿Por qué saludar() no necesita parámetros?

Porque usa los valores ya guardados dentro del objeto mediante this.

6. ¿Para qué sirve export en una clase?

Para permitir que esa clase pueda importarse y usarse desde otros archivos.

7. ¿Qué significa el principio "un archivo, una clase"?

Que cada clase vive en su propio archivo para mantener orden y facilitar reutilización.

📎 Apuntes relacionados

➡️ Siguiente

Modificadores de acceso, herencia y más POO (public, private, extends).