Menu
Coddy logo textTech

Default и Static методы в интерфейсах

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy — урок 37 из 87.

Изначально интерфейсы могли содержать только абстрактные методы без реализации. Начиная с Java 8, интерфейсы получили возможность включать методы по умолчанию и статические методы, что сделало их более гибкими.

Метод по умолчанию предоставляет реализацию непосредственно в интерфейсе с помощью ключевого слова default. Классы, реализующие интерфейс, автоматически наследуют это поведение, но при необходимости могут его переопределить:

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

Любой класс, реализующий Drawable, получает метод display() бесплатно. Это особенно полезно для добавления новых методов в существующие интерфейсы без нарушения работы классов, которые их уже реализуют.

Статические методы в интерфейсах работают так же, как статические методы в классах. Они принадлежат самому интерфейсу и вызываются с использованием имени интерфейса:

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

// Использование
int result = MathOperations.add(5, 3);

Статические методы интерфейса не могут быть переопределены и не наследуются реализующими классами. Они полезны для вспомогательных методов, связанных с назначением интерфейса.

Если класс реализует два интерфейса с одинаковой сигнатурой метода по умолчанию, класс должен переопределить этот метод для разрешения конфликта.

challenge icon

Задание

Легко

Давайте создадим систему обмена сообщениями, которая демонстрирует использование как методов по умолчанию (default), так и статических методов в интерфейсах. Вы создадите интерфейс со встроенной функциональностью, которую реализующие классы смогут использовать напрямую или настраивать по мере необходимости.

Вы организуете свой код в четырех файлах:

  • Messenger.java: Определите интерфейс, представляющий любую службу обмена сообщениями. Он должен объявлять абстрактный метод sendMessage(String message), который возвращает void. Добавьте метод по умолчанию с именем sendWithTimestamp(String message), который выводит: [TIMESTAMP] , после чего вызывает sendMessage(message). Также включите статический метод с именем formatMessage(String message), который возвращает сообщение, преобразованное в верхний регистр.
  • EmailMessenger.java: Создайте класс, реализующий Messenger. У него есть поле recipient (String). Включите конструктор для инициализации получателя. Реализуйте sendMessage() для вывода: Email to [recipient]: [message]. Этот класс использует метод по умолчанию sendWithTimestamp() как есть.
  • SMSMessenger.java: Создайте еще один класс, реализующий Messenger. У него есть поле phoneNumber (String). Включите конструктор для инициализации номера телефона. Реализуйте sendMessage() для вывода: SMS to [phoneNumber]: [message]. Переопределите метод по умолчанию sendWithTimestamp(), чтобы он выводил: [URGENT] , а затем вызывал sendMessage(message) вместо использования поведения по умолчанию с меткой времени.
  • Main.java: Объедините все вместе, чтобы продемонстрировать работу методов интерфейса по умолчанию и статических методов. Вы получите три входных значения: получателя электронной почты, номер телефона и сообщение. Сначала используйте статический метод Messenger.formatMessage(), чтобы отформатировать сообщение и сохранить его. Затем создайте EmailMessenger и SMSMessenger. Для каждого мессенджера вызовите sendWithTimestamp() с отформатированным сообщением — обратите внимание, как EmailMessenger использует реализацию по умолчанию, в то время как SMSMessenger использует свою переопределенную версию.

Вы получите три входных значения: получатель электронной почты (String), номер телефона (String) и сообщение (String).

Ваш вывод должен содержать всего четыре строки — по две для каждого мессенджера: строку с префиксом ([TIMESTAMP] или [URGENT]), за которой следует строка с сообщением. EmailMessenger покажет префикс метки времени по умолчанию, а SMSMessenger покажет свой собственный префикс срочности. Оба будут использовать статически отформатированное сообщение (в верхнем регистре)!

Попробуйте сами

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Чтение входных данных
        String emailRecipient = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        String message = scanner.nextLine();
        
        // TODO: Используйте Messenger.formatMessage() для форматирования сообщения и сохраните его
        
        // TODO: Создайте EmailMessenger с получателем электронной почты
        
        // TODO: Создайте SMSMessenger с номером телефона
        
        // TODO: Вызовите sendWithTimestamp() у EmailMessenger с отформатированным сообщением
        
        // TODO: Вызовите sendWithTimestamp() у SMSMessenger с отформатированным сообщением
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование