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 predeterminado 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 particularmente ú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 propia interfaz 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 de interfaz estáticos 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 integrada 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] 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 almacenarlo. Luego crea un EmailMessenger y un SMSMessenger. Para cada mensajero, llama a sendWithTimestamp() con el mensaje formateado; observa cómo el 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 debería mostrar cuatro líneas en total, dos para cada mensajero. 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)!

Hoja de referencia

A partir de Java 8, las interfaces pueden incluir métodos predeterminados y métodos estáticos además de los métodos abstractos.

Los métodos predeterminados proporcionan 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();
    }
}

Los métodos estáticos en las interfaces pertenecen a la interfaz misma y se llaman utilizando el nombre de la interfaz. No se pueden sobrescribir y no son heredados por las clases que las implementan:

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

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

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.

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: Usar Messenger.formatMessage() para formatear el mensaje y guardarlo
        
        // TODO: Crear un EmailMessenger con el destinatario del correo electrónico
        
        // TODO: Crear un SMSMessenger con el número de teléfono
        
        // TODO: Llamar a sendWithTimestamp() en el EmailMessenger con el mensaje formateado
        
        // TODO: Llamar 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