Menu
Coddy logo textTech

Metody domyślne i statyczne w interfejsie

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 37 z 87.

Pierwotnie interfejsy mogły zawierać wyłącznie metody abstrakcyjne bez implementacji. Począwszy od Java 8, interfejsy zyskały możliwość zawierania metod domyślnych i metod statycznych, co zwiększyło ich elastyczność.

Metoda domyślna zapewnia implementację bezpośrednio w interfejsie przy użyciu słowa kluczowego default. Klasy implementujące interfejs automatycznie dziedziczą to zachowanie, ale w razie potrzeby mogą je nadpisać:

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

Każda klasa implementująca Drawable otrzymuje metodę display() za darmo. Jest to szczególnie przydatne przy dodawaniu nowych metod do istniejących interfejsów bez naruszania klas, które już je implementują.

Metody statyczne w interfejsach działają jak metody statyczne w klasach. Należą do samego interfejsu i są wywoływane przy użyciu nazwy interfejsu:

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

// Użycie
int result = MathOperations.add(5, 3);

Statycznych metod interfejsu nie można przesłonić i nie są one dziedziczone przez klasy implementujące interfejs. Przydają się w przypadku metod pomocniczych związanych z przeznaczeniem interfejsu.

Jeśli klasa implementuje dwa interfejsy z taką samą sygnaturą metody domyślnej, klasa musi nadpisać tę metodę, aby rozwiązać konflikt.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system wiadomości, który pokazuje zarówno metody domyślne, jak i statyczne w interfejsach. Utworzysz interfejs z wbudowaną funkcjonalnością, z której klasy implementujące go mogą korzystać bezpośrednio lub którą mogą dostosować do swoich potrzeb.

Rozmieścisz kod w czterech plikach:

  • Messenger.java: Zdefiniuj interfejs reprezentujący dowolną usługę do wysyłania wiadomości. Powinien deklarować abstrakcyjną metodę sendMessage(String message), która zwraca void. Dodaj metodę domyślną o nazwie sendWithTimestamp(String message), która wyświetla: [TIMESTAMP] , a następnie wywołuje sendMessage(message). Uwzględnij też metodę statyczną o nazwie formatMessage(String message), która zwraca wiadomość zamienioną na wielkie litery.
  • EmailMessenger.java: Utwórz klasę implementującą Messenger. Ma pole recipient typu String. Dodaj konstruktor inicjujący odbiorcę. Zaimplementuj sendMessage(), aby wyświetlała: Email to [recipient]: [message]. Ta klasa korzysta z domyślnej metody sendWithTimestamp() bez zmian.
  • SMSMessenger.java: Utwórz kolejną klasę implementującą Messenger. Ma pole phoneNumber typu String. Dodaj konstruktor inicjujący numer telefonu. Zaimplementuj sendMessage(), aby wyświetlała: SMS to [phoneNumber]: [message]. Nadpisz domyślną metodę sendWithTimestamp(), aby wyświetlała: [URGENT] , a następnie wywoływała sendMessage(message) zamiast korzystać z domyślnego zachowania dodającego znacznik czasu.
  • Main.java: Połącz wszystko, aby zaprezentować domyślne i statyczne metody interfejsu. Otrzymasz trzy dane wejściowe: odbiorcę wiadomości e-mail, numer telefonu i wiadomość. Najpierw użyj metody statycznej Messenger.formatMessage(), aby sformatować wiadomość i ją zapisać. Następnie utwórz obiekt EmailMessenger i obiekt SMSMessenger. Dla każdego z nich wywołaj sendWithTimestamp() z sformatowaną wiadomością: zwróć uwagę, że EmailMessenger używa implementacji domyślnej, a SMSMessenger — jej nadpisanej wersji.

Otrzymasz trzy dane wejściowe: odbiorcę wiadomości e-mail (String), numer telefonu (String) i wiadomość (String).

Wynik powinien składać się łącznie z czterech wierszy: po dwa dla każdego obiektu do wysyłania wiadomości — wiersza z prefiksem ([TIMESTAMP] lub [URGENT]), a po nim wiersza z wiadomością. EmailMessenger wyświetli domyślny prefiks znacznika czasu, a SMSMessenger — własny, pilny prefiks. W obu przypadkach wiadomość będzie sformatowana statycznie (zapisana wielkimi literami)!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Wczytaj dane wejściowe
        String emailRecipient = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        String message = scanner.nextLine();
        
        // TODO: Użyj Messenger.formatMessage(), aby sformatować wiadomość i ją zapisać
        
        // TODO: Utwórz EmailMessenger z adresem e-mail odbiorcy
        
        // TODO: Utwórz SMSMessenger z numerem telefonu
        
        // TODO: Wywołaj sendWithTimestamp() na EmailMessenger, przekazując sformatowaną wiadomość
        
        // TODO: Wywołaj sendWithTimestamp() na SMSMessenger, przekazując sformatowaną wiadomość
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online