SLIDE 1 / 5

1. El Filtro Mental: "Es un" vs "Tiene un"

La herencia (extends) genera el acoplamiento más fuerte en POO. Si la relación no pasa la prueba estricta "X es un Y", NUNCA se hereda: se compone mediante un campo privado ("X tiene un Y").

✓ Herencia Válida ("Es un") Vehiculo arrancar() | frenar() Auto Auto extends Vehiculo Regla: Todo Auto ES un Vehículo ✕ Anti-Patrón de Modelado Motor cilindrada, rpm ¿Auto extends Motor? ✕ ¡NO! Auto (Composición) private Motor motor; ◆ Solución: Auto TIENE un Motor
Test de Relación
Pregunta Conceptual: ¿Un Auto es un Vehículo?
Veredicto Arquitectura: HERENCIA (extends)
Razón de Diseño: Sustitución Liskov 100% válida.
// Herencia limpia: Auto ES UN Vehículo
public class Auto extends Vehiculo {
  private Motor motor; // Composición interna
}

2. El Heap en Capas y el Encadenamiento con super()

Al hacer new Auto("Toyota"), NO se crean dos objetos en memoria. Se crea un ÚNICO bloque en el Heap organizado en capas. Por contrato de la JVM, la superclase se construye primero mediante super() antes de que corra el código de la subclase.

Objeto Único en Heap @0x7B20 new Auto("Toyota", true) Capa Externa: Auto baulAbierto = true Núcleo: Vehiculo (super) marca = "Toyota" velocidad = 0 Orden de Ejecución 1 new Auto("Toyota") Entrada al constructor Auto 2 super("Toyota") 1ra línea: cede control a Vehiculo 3 Núcleo Vehiculo Listo Atributos base inicializados 4 Cuerpo de Auto this.baulAbierto = true
Traza de Constructores
Fase Actual: 1. Invocación de new Auto()
Regla JVM Obligatoria: super() siempre se ejecuta primero
public Auto(String marca) {
  super(marca); // <-- ¡Debe ser la 1ra sentencia!
  this.baulAbierto = false;
}

3. Sobrecarga vs Sobrescritura: Compilación vs Runtime

Sobrecarga (Overload): misma clase, mismo nombre, parámetros diferentes; resuelto estáticamente por javac. Sobrescritura (Override): herencia, misma firma; resuelto en caliente por la JVM según el objeto real.

Sobrecarga (Overload) void acelerar(int kmh) void acelerar(int kmh, boolean turbo) Ámbito: Misma clase Resuelto por: javac (Estático) Firma distinta; no requiere herencia. Sobrescritura (@Override) Vehiculo: void arrancar() Auto: @Override void arrancar() Ámbito: Subclase (Herencia) Resuelto por: JVM (Dinámico) Misma firma; reemplaza comportamiento base.
Peligro Sin @Override
Anotación: @Override presente
Diagnóstico Compilador: ✓ Sobrescritura validada
Efecto en Runtime: Despacho dinámico a la subclase.
// El compilador verifica que la firma coincida
@Override
public void arrancar() {
  System.out.println("Auto arrancando con llave codificada");
}

4. Despacho Dinámico y la Tabla de Métodos Virtuales (vtable)

Con `Vehiculo v = new Auto()`, el compilador valida el tipo estático (Vehiculo). Pero al invocar `v.arrancar()`, la JVM consulta en runtime la vtable del objeto concreto en el Heap y salta directamente al código de Auto.

Stack Vehiculo v (Tipo estático) @0x4000 → Heap @0x4000 new Auto("Toyota") Header / Klass Pointer: → Auto.class (vtable) Campos en memoria: marca: "Toyota" vtable: Punteros de Código toString() -> Object arrancar() → Auto.arrancar() ¡Ejecuta Auto en caliente!
Simulador de Despacho
Tipo Estático (Compilación): Vehiculo
Tipo Dinámico (Heap): Auto
Entrada vtable consultada: Auto.arrancar()
Vehiculo v = new Auto("Toyota");
v.arrancar(); // JVM consulta vtable -> Auto.arrancar()

5. Arrays Polimórficos y Pattern Matching

Un array heterogéneo `Vehiculo[]` permite manipular distintos objetos de manera uniforme sin usar switch ni condicionales. Para acceder a métodos exclusivos de una subclase, Java 16+ ofrece Pattern Matching para instanceof.

Vehiculo[] flota = { auto, moto, camion }; [0] Auto arrancar() abrirBaul() *exclusivo [1] Moto arrancar() hacerWheelie() *exclusivo [2] Camion arrancar() cargarRemolque() *exclusivo for (Vehiculo v : flota) { v.arrancar(); } ✓ Auto arrancando con llave codificada [Rummm suave] Pattern matching: if (v instanceof Auto a) -> a.abrirBaul();
Ejecución Polimórfica
Elemento Actual: flota[0] -> Auto
Comportamiento Ejecutado: Auto.arrancar()
for (Vehiculo v : flota) {
  v.arrancar(); // Polimorfismo puro

  // Java 16+ Pattern Matching (sin cast manual):
  if (v instanceof Auto a) {
    a.abrirBaul();
  }
}