Menu
Coddy logo textTech

Métodos Default y Static en Interfaces

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

Originalmente, las interfaces solo podían contener métodos abstractos sin implementación. A partir de Java 8, las interfaces adquirieron la capacidad de incluir métodos predeterminados y métodos estáticos, lo que las hizo más flexibles.

Un método predeterminado proporciona una implementación directamente en la interfaz mediante la palabra clave default. Las clases que implementan la interfaz heredan este comportamiento automáticamente, pero pueden sobrescribirlo si es necesario:

public interface Drawable {
    void draw();
    
    default void display() {
        System.out.println("Displaying on screen...");
        draw();
    }
}

Cualquier clase que implemente Drawable obtiene el método display() gratis. Esto resulta especialmente útil para añadir nuevos métodos a interfaces existentes sin romper las clases que ya los implementan.

Los métodos estáticos en las interfaces funcionan como los métodos estáticos en las clases. Pertenecen a la propia interfaz y se llaman usando el nombre de la interfaz:

public interface MathOperations {
    static int add(int a, int b) {
        return a + b;
    }
}

// Uso
int result = MathOperations.add(5, 3);

Los métodos estáticos de las interfaces no se pueden sobrescribir y las clases que las implementan no los heredan. Son útiles para métodos de utilidad relacionados con el propósito de la interfaz.

Si una clase implementa dos interfaces con la misma firma de método predeterminado, la clase debe sobrescribir ese método para resolver el conflicto.

challenge icon

Desafío

Fácil

Construyamos un sistema de mensajería que muestre tanto los métodos predeterminados como los estáticos en las interfaces. Crearás una interfaz con funcionalidad incorporada que las clases que la implementen puedan usar directamente o personalizar según sea necesario.

Organizarás tu código en cuatro archivos:

  • Messenger.java: Define una interfaz que represente cualquier servicio de mensajería. Debe declarar un método abstracto sendMessage(String message) que devuelva void. Añade un método predeterminado llamado sendWithTimestamp(String message) que imprima: [TIMESTAMP] y después llame a sendMessage(message). Incluye también un método estático llamado formatMessage(String message) que devuelva el mensaje convertido a mayúsculas.
  • EmailMessenger.java: Crea una clase que implemente Messenger. Tiene un campo recipient (String). Incluye un constructor para inicializar el destinatario. Implementa sendMessage() para imprimir: Email to [recipient]: [message]. Esta clase usa el método predeterminado sendWithTimestamp() tal cual.
  • SMSMessenger.java: Crea otra clase que implemente Messenger. Tiene un campo phoneNumber (String). Incluye un constructor para inicializar el número de teléfono. Implementa sendMessage() para imprimir: SMS to [phoneNumber]: [message]. Sobrescribe el método predeterminado sendWithTimestamp() para imprimir: [URGENT] y después llamar a sendMessage(message), en lugar de usar el comportamiento de marca de tiempo predeterminado.
  • Main.java: Reúne todo para demostrar los métodos predeterminados y estáticos de las interfaces. Recibirás tres entradas: un destinatario de correo electrónico, un número de teléfono y un mensaje. Primero, usa el método estático Messenger.formatMessage() para dar formato al mensaje y almacenarlo. Después, crea un EmailMessenger y un SMSMessenger. Para cada mensajero, llama a sendWithTimestamp() con el mensaje al que se le ha dado formato: observa cómo EmailMessenger usa la implementación predeterminada, mientras que SMSMessenger usa su versión sobrescrita.

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

Tu salida debe mostrar cuatro líneas en total: dos por cada mensajero: una línea de prefijo ([TIMESTAMP] o [URGENT]) seguida de la línea del mensaje. EmailMessenger mostrará el prefijo de marca de tiempo predeterminado, mientras que SMSMessenger mostrará su prefijo urgente personalizado. ¡Ambos usarán el mensaje al que se le ha dado formato estáticamente (en mayúsculas)!

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 emailRecipient = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        String message = scanner.nextLine();
        
        // TODO: Usa Messenger.formatMessage() para formatear el mensaje y almacenarlo
        
        // TODO: Crea un EmailMessenger con el destinatario del email
        
        // TODO: Crea un SMSMessenger con el número de teléfono
        
        // TODO: Llama a sendWithTimestamp() en el EmailMessenger con el mensaje formateado
        
        // TODO: Llama a sendWithTimestamp() en el SMSMessenger con el mensaje formateado
    }
}
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