Interfejsy

Interfejs to swego rodzaju warstwa abstrakcji która narzuca programiście implementację, w klasach potomnych, metod które ma w sobie zdefiniowane.
Owe metody są tylko sygnaturą, nie ma ciała metody, nie ma implementacji (to wszystko należy umieścić w klasie implementującej dany interfejs).
W odróżnieniu od klasycznego diedziczenia (klasa po klasie) gdzie nie występuje wielodziedziczenie (jedna klasa może dziedziczyć wyłącznie po jednej klasie) interfejsów w klasie można implementować wiele.
Do implementacji służy słówko implements.

Interfejs Math:

public interface Math {
    double add(double a, double b);
    double subtract(double a, double b);
    double multiply(double a, double b);
    double divide(double a, double b);
}

Klasa implementująca interfejs(przesłaniająca i implementująca jego metody):

class Calculator implements Math {
    @Override
    public double add(double a, double b) {
        return a+b;
    }
    @Override
    public double subtract(double a, double b) {
        return a-b;
    }
    @Override
    public double multiply(double a, double b) {
        return a*b;
    }
    @Override
    public double divide(double a, double b) {
        return a/b;
    }
}

Klasa testowa:

public class CalculatorTest {
    public static void main(String args[]) {
        Calculator calc = new Calculator();
        double a = 20;
        double b = 3.5;

        System.out.println("Wynik dodawania: "+calc.add(a, b));
        System.out.println("Wynik odejmowania: "+calc.subtract(a, b));
        System.out.println("Wynik mnożenia: "+calc.multiply(a, b));
        System.out.println("Wynik dzielenia: "+calc.divide(a, b));

        //zastosowanie zmiennej referencyjnej
        Math math;
        math = calc;
        //Math math = new Calculator();
        System.out.println("Użycie referencji interfejsu: "+math.add(a, b));
    }
}

Wyżej widać zastosowanie referencji interfejsu, klasa implementuje interfejs Math więc jej obiekty możemy zrzutawać na typ interfejsowy. Wywołanie metody dla takiej zmiennej spowoduje wywołanie odpowiedniej wersji metody należącej do właściwego egzemplarza klasy.

Stosowanie interfejsów pomaga tworzyć elastyczny kod uniezależniony od implementacji tworząc tzw. luźne związki („Uzależniaj kod od abstrakcji a nie od klas rzeczywistych”). Co więcej interfejsy są powszechnie stosowane w najróżniejszych wzorcach projektowych dlatego warto je znać i rozumieć.

Metody domyślne
W wersji 8 javy pojawiły się metody domyślne interfejsu, które oznaczamy słowem kluczowym default. Są to metody, które nie są abstrakcyjne, a więc nie muszą być przesłaniane w klasach implementujących dany interfejs.

public interface Math {
    default double add(double a, double b);
    double subtract(double a, double b);
    double multiply(double a, double b);
    default double divide(double a, double b);
}

Metody prywatne
W celu rozwiązania problemu hermetyzacji metod w javie, w wersji 9, wprowadzono metody prywatne (oznacza się je słówkiem private).

public interface Math {
    private double add(double a, double b);
    double subtract(double a, double b);
    double multiply(double a, double b);
    private double divide(double a, double b);
}

Nie należy nadużywać metod domyślnych i prywatnych ponieważ grozi to uzależnieniem systemu od implementacji co prowadzi do zmniejszenia elastyczności i jest złą praktyką.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *