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 hace más flexibles.

Un método por defecto proporciona una implementación directamente en la interfaz utilizando 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() de forma gratuita. Esto es especialmente útil para añadir nuevos métodos a interfaces existentes sin romper las clases que ya las implementan.

Los métodos estáticos en las interfaces funcionan como los métodos estáticos en las clases. Pertenecen a la interfaz misma y se llaman utilizando 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 interfaz no pueden ser sobrescritos y no son heredados por las clases que los implementan. 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

Vamos a construir 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 implementadoras pueden 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] seguido de la llamada a sendMessage(message). También incluye 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 utiliza 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] seguido de la llamada a sendMessage(message) en lugar de usar el comportamiento de marca de tiempo predeterminado.
  • Main.java: Reúne todo para demostrar tanto los métodos de interfaz predeterminados como los estáticos. 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 formatear el mensaje y guardarlo. Luego crea un EmailMessenger y un SMSMessenger. Para cada mensajero, llama a sendWithTimestamp() con el mensaje formateado; observa cómo EmailMessenger usa la implementación predeterminada mientras que SMSMessenger usa su versión sobrescrita.

Recibirás tres entradas: el destinatario del 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. El EmailMessenger mostrará el prefijo de marca de tiempo predeterminado, mientras que el SMSMessenger mostrará su prefijo urgente personalizado. ¡Ambos usarán el mensaje formateado 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: Use Messenger.formatMessage() para formatear el mensaje y almacenarlo
        
        // TODO: Cree un EmailMessenger con el destinatario del correo electrónico
        
        // TODO: Cree un SMSMessenger con el número de teléfono
        
        // TODO: Llame a sendWithTimestamp() en el EmailMessenger con el mensaje formateado
        
        // TODO: Llame 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