Menu
Coddy logo textTech

Sobrescritura de métodos (tiempo de ejecución)

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 29 de 87.

Mientras que la sobrecarga de métodos se resuelve en tiempo de compilación, la sobreescritura de métodos demuestra el polimorfismo en tiempo de ejecución. Aquí, Java decide qué método ejecutar cuando el programa se está ejecutando realmente, basándose en el tipo real del objeto en lugar del tipo declarado de la variable.

Aprendiste sobre la sobrescritura de métodos en el capítulo de Herencia. Lo que lo hace polimórfico es cómo Java lo maneja cuando una referencia de padre apunta a un objeto hijo:

public class Animal {
    public void speak() {
        System.out.println("Some sound");
    }
}

public class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Bark!");
    }
}

public class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Meow!");
    }
}

Ahora observa lo que sucede cuando usamos referencias de tipo padre:

Animal myPet = new Dog();
myPet.speak();  // Salida: Bark!

myPet = new Cat();
myPet.speak();  // Salida: Meow!

Aunque myPet está declarada como Animal, Java llama al método sobrescrito basándose en el tipo de objeto real en tiempo de ejecución. Esto se llama despacho dinámico de métodos. La JVM observa lo que el objeto es realmente, no lo que dice la variable que es.

Esto permite patrones potentes como el procesamiento de diferentes objetos de manera uniforme:

Animal[] pets = {new Dog(), new Cat(), new Dog()};
for (Animal pet : pets) {
    pet.speak();  // Cada uno llama a su propia versión
}

El polimorfismo en tiempo de ejecución te permite escribir código flexible que funciona con tipos padre mientras utiliza automáticamente el comportamiento correcto de la clase hija.

challenge icon

Desafío

Fácil

Construyamos un sistema de notificaciones que demuestre el polimorfismo en tiempo de ejecución en acción. Crearás una jerarquía de tipos de notificación en la que la misma llamada a un método produce diferentes resultados según el tipo real del objeto en tiempo de ejecución.

Organizarás tu código en cuatro archivos:

  • Notification.java: Crea la clase base que comparten todas las notificaciones. Cada notificación tiene un campo recipient (String). Incluye un constructor para inicializarlo, un método getter y un método send() que imprime: Sending notification to [recipient]
  • EmailNotification.java: Crea una clase que extienda Notification. Las notificaciones por correo electrónico agregan un campo subject. Usa super para la inicialización del padre. Sobrescribe el método send() para imprimir: Emailing [recipient]: [subject]
  • SMSNotification.java: Crea otra clase que extienda Notification. Las notificaciones SMS agregan un campo phoneNumber. Sobrescribe send() para imprimir: Texting [phoneNumber] for [recipient]
  • Main.java: ¡Aquí es donde brilla el polimorfismo en tiempo de ejecución! Recibirás tres entradas: un nombre de destinatario, un asunto de correo electrónico y un número de teléfono. Crea un arreglo de referencias de Notification que contenga tres objetos en este orden: una Notification base, una EmailNotification y una SMSNotification (todas usando el mismo destinatario). Después, recorre el arreglo y llama a send() en cada elemento. ¡Observa cómo Java llama automáticamente a la versión sobrescrita correcta según lo que realmente sea cada objeto!

Recibirás tres entradas: el nombre del destinatario (String), el asunto del correo electrónico (String) y el número de teléfono (String).

Tu salida debe mostrar tres líneas: cada llamada a send() produce una salida diferente aunque estés llamando al mismo método sobre referencias de Notification. ¡Ese es el despacho dinámico de métodos en acción!

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer entradas
        String recipient = scanner.nextLine();
        String subject = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        
        // TODO: Crear un arreglo de referencias de Notification con 3 elementos
        // El arreglo debe contener (en este orden):
        // 1. Un objeto Notification base
        // 2. Un objeto EmailNotification
        // 3. Un objeto SMSNotification
        // Todos usando el mismo recipient
        
        // TODO: Recorrer el arreglo y llamar a send() en cada elemento
        // ¡Esto demuestra el polimorfismo en tiempo de ejecución!
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online