Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Jhaymayleth/unidad2_java/llms.txt

Use this file to discover all available pages before exploring further.

Polymorphism — Greek for “many shapes” — is the ability to treat objects of different classes through a single common type, while each object still behaves according to its own specific implementation. In Java, this happens automatically at runtime: the JVM looks at the actual type of the object, not the type of the variable holding it, and calls the right method. The result is code that is both general and precise — written once in terms of a parent type, it works correctly for every subclass without a single if-statement.

A Parent Reference Holding a Child Object

Java allows you to assign a subclass instance to a variable whose declared type is the parent class:
PersonaT10 p1 = new EstudianteT10("Pedro", "Diseño Gráfico");
PersonaT10 p2 = new ProfesorT10("Laura", "Física");
p1 and p2 are typed as PersonaT10, but they actually hold EstudianteT10 and ProfesorT10 objects. When you call a method on them, the JVM dispatches to the subclass version — this is called dynamic dispatch.

Method Overriding with @Override

Overriding means a subclass provides its own implementation of a method that already exists in the parent, using the exact same signature (name, parameter types, and return type). The @Override annotation tells the compiler to verify this — if the signature doesn’t match any parent method, compilation fails immediately.
// PersonaT10.java
class PersonaT10 {
    String nombre;

    public PersonaT10(String nombre) {
        this.nombre = nombre;
    }

    public void presentarse() {
        System.out.println("Hola, soy " + nombre + ".");
    }
}
// EstudianteT10.java
class EstudianteT10 extends PersonaT10 {
    String carrera;

    public EstudianteT10(String nombre, String carrera) {
        super(nombre);
        this.carrera = carrera;
    }

    @Override
    public void presentarse() {
        System.out.println("Hola, soy " + nombre + " y estudio " + carrera + ".");
    }
}
// ProfesorT10.java
class ProfesorT10 extends PersonaT10 {
    String especialidad;

    public ProfesorT10(String nombre, String especialidad) {
        super(nombre);
        this.especialidad = especialidad;
    }

    @Override
    public void presentarse() {
        System.out.println("Hola, soy el profesor " + nombre
                + " y mi especialidad es " + especialidad + ".");
    }
}

Dynamic Dispatch in Action

MainEjercicio1T10 shows the full picture — concrete calls and polymorphic calls side by side:
public class MainEjercicio1T10 {
    public static void main(String[] args) {

        // Concrete references — type matches the object
        PersonaT10   persona    = new PersonaT10("Carlos");
        EstudianteT10 estudiante = new EstudianteT10("Ana", "Ingeniería de Software");
        ProfesorT10  profesor   = new ProfesorT10("María", "Matemáticas");

        persona.presentarse();    // "Hola, soy Carlos."
        estudiante.presentarse(); // "Hola, soy Ana y estudio Ingeniería de Software."
        profesor.presentarse();   // "Hola, soy el profesor María..."

        System.out.println("\n--- Polimorfismo ---");

        // Parent-typed references holding child objects — dynamic dispatch
        PersonaT10 p1 = new EstudianteT10("Pedro", "Diseño Gráfico");
        PersonaT10 p2 = new ProfesorT10("Laura", "Física");

        p1.presentarse(); // calls EstudianteT10.presentarse() — "Hola, soy Pedro y estudio..."
        p2.presentarse(); // calls ProfesorT10.presentarse()  — "Hola, soy el profesor Laura..."
    }
}
Even though p1 is declared as PersonaT10, the JVM calls EstudianteT10.presentarse() because the underlying object is an EstudianteT10. The compile-time type determines what you can call; the runtime type determines which implementation runs.

Overloading vs. Overriding

These two concepts are easy to confuse. The key distinction is the method signature:
SignatureResolved atAnnotation
OverridingIdentical to parentRuntime@Override required (best practice)
OverloadingDifferent parameter listCompile-timeNot applicable
MainEjercicio3T10 demonstrates the pitfall of confusing the two. ClaseDerivadaT10 attempts to “override” metodoSobrescrito() by adding a parameter — but this creates an overloaded method, not an overridden one. The original metodoSobrescrito() is still there, just silently unoverridden:
class ClaseBaseT10 {
    public void metodoSobrescrito() {
        System.out.println("Método sobrescrito de ClaseBaseT10.");
    }
}

class ClaseDerivadaT10 extends ClaseBaseT10 {

    // ⚠️ This is an OVERLOAD, not an override — different signature
    public void metodoSobrescrito(int numero) {
        System.out.println("Método sobrecargado de ClaseDerivadaT10 con número: " + numero);
    }

    // This IS an override — same signature — but missing @Override (bad practice)
    public void metodoSobrescrito() {
        System.out.println("Método sobrescrito de ClaseDerivadaT10 (sin @Override).");
    }
}
The clearest way to see the danger: if ClaseBaseT10 later renames its method, the “override” in ClaseDerivadaT10 silently becomes an unrelated method. @Override would have caught the mismatch immediately.

Correct @Override vs. Accidental Overload

// ✅ CORRECT — override, same signature, compiler-verified
class CorrectSubclass extends ClaseBaseT10 {
    @Override
    public void metodoSobrescrito() {
        System.out.println("Correctly overriding the parent method.");
    }
}

// ❌ DANGEROUS — this is an overload, not an override
//    The parent's metodoSobrescrito() is still inherited unchanged
class BuggySubclass extends ClaseBaseT10 {
    public void metodoSobrescrito(int numero) {  // different signature!
        System.out.println("I thought I was overriding, but I'm not.");
    }
}
Always annotate intended overrides with @Override. The annotation costs nothing and makes the compiler catch any signature mismatch at compile time — before it becomes a hard-to-debug runtime surprise.

Build docs developers (and LLMs) love