Przejdź do głównej treści
eLearner.app
Moduł 4 · Lekcja 1 z 27/14 w kursie~15 min
Lekcje modułu (1/2)

Interfejsy

Podczas gdy klasy abstrakcyjne mogą zawierać zarówno częściowo zaimplementowany kod, jak i pola instancji, interfejsy w Javie są kontraktami czystego zachowania. Interfejs definiuje co klasa musi umieć zrobić, ale nie jak to robi.

Pozwala to na całkowite uniezależnienie definicji operacji od ich rzeczywistej implementacji.

Definiowanie interfejsu (interface)

Używa się słowa kluczowego interface. Wszystkie metody zadeklarowane w interfejsie są implikowanie public i abstract (nie ma potrzeby tego określać):

Code
interface Drivable {
    void startEngine();
    void stopEngine();
}

Implementowanie interfejsu (implements)

Klasa implementuje interfejs za pomocą słowa kluczowego implements i jest zobowiązana do dostarczenia implementacji (z ciałem) dla wszystkich zdefiniowanych metod:

Code
class Motorcycle implements Drivable {
    @Override
    public void startEngine() {
        System.out.println("Rombo del motore acceso!");
    }

    @Override
    public void stopEngine() {
        System.out.println("Motore spento.");
    }
}

Zalety interfejsów

  1. Wielokrotne dziedziczenie: W Javie klasa może rozszerzać tylko jedną klasę nadrzędną (dziedziczenie pojedyncze), ale może implementować wiele interfejsów jednocześnie.
    Code
    class HybridCar implements Drivable, Chargeable { ... }
    
  2. Luźne powiązanie (Desacoplamiento): Możesz definiować zmienne przy użyciu typu interfejsu. Dowolny obiekt implementujący ten interfejs może zostać przypisany do tej zmiennej.
    Code
    Drivable vehicle = new Motorcycle();
    vehicle.startEngine();
    

Stałe w interfejsach

W interfejsach możliwe jest deklarowanie pól. Pola te są implikowanie public static final (czyli stałymi klasowymi), nawet jeśli nie określimy tych modyfikatorów. W związku z tym muszą być zainicjalizowane natychmiast w momencie deklaracji:

Code
interface PhysicsConstants {
    double GRAVITY = 9.81; // Implicitamente public static final
}

Metody domyślne (default)

Począwszy od Javy 8, możliwe jest definiowanie metod z domyślną implementacją wewnątrz interfejsu za pomocą słowa kluczowego default. Metody te nie zmuszają klas implementujących interfejs do ich nadpisywania, zapewniając zachowanie awaryjne (fallback):

Code
interface Logger {
    void log(String message);

    // Metodo di default con corpo
    default void logError(String message) {
        log("ERRORE: " + message);
    }
}

Spróbuj sam

Ćwiczenie#java.m4.l1.e1
Próby: 0Ładowanie...

Utwórz interfejs Flyable z metodą void fly(). Następnie zaimplementuj klasę Bird tak, aby implementowała Flyable i wypisywała Flying na ekranie.

Ładowanie edytora...
Pokaż wskazówkę

W Flyable wpisz `void fly();`. W klasie Bird zaimplementuj metodę, oznaczając ją `@Override public void fly() { System.out.println('Flying'); }`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie#java.m4.l1.e2
Próby: 0Ładowanie...

Zdefiniuj interfejs Drawable z metodą void draw(). Następnie zaimplementuj klasę Rectangle tak, aby implementowała Drawable i wypisywała Drawing Rectangle.

Ładowanie edytora...
Pokaż wskazówkę

Zdefiniuj `void draw();` w interfejsie. W Rectangle użyj `@Override public void draw() { System.out.println('Drawing Rectangle'); }`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie#java.m4.l1.e3
Próby: 0Ładowanie...

Uzupełnij interfejs Swimmable, definiując metodę void swim(). Następnie uzupełnij klasę Duck tak, aby implementowała zarówno Flyable, jak i Swimmable, wypisując Flying w metodzie fly() i Swimming w metodzie swim().

Ładowanie edytora...
Pokaż wskazówkę

Zadeklaruj `void swim();` w Swimmable. Zadeklaruj `class Duck implements Flyable, Swimmable` i zaimplementuj obie metody wypisując wymagane ciągi znaków.

Rozwiązanie dostępne po 3 próbach