W Javie 8 i późniejszych, odpowiedź na to pytanie jest nadal aktualna, ale teraz jest bardziej zniuansowana.
Po pierwsze, te stwierdzenia z zaakceptowanej odpowiedzi pozostają poprawne:
- interfejsy mają na celu określenie ich niejawnych zachowań w umowie (zestawienie zasad zachowania, które muszą spełniać klasy implementujące, aby zostały uznane za prawidłowe)
- istnieje rozróżnienie między umową (zasadami) a wdrożeniem (programowe kodowanie zasad)
- metody określone w interfejsie MUSZĄ być ZAWSZE implementowane (w pewnym momencie)
A więc jakie są nowe niuanse w Javie 8? Mówiąc o „metodach opcjonalnych”, można zastosować dowolne z poniższych:
1. Metoda, której wdrożenie jest umownie opcjonalne
„Trzecie stwierdzenie” mówi, że abstrakcyjne metody interfejsu muszą być zawsze implementowane i tak jest w Javie 8+. Jednak, podobnie jak w Java Collections Framework, niektóre abstrakcyjne metody interfejsu można opisać jako „opcjonalne” w kontrakcie.
W takim przypadku autor implementujący interfejs może zrezygnować z implementacji metody. Kompilator będzie jednak nalegał na implementację, więc autor używa tego kodu dla dowolnych metod opcjonalnych, które nie są potrzebne w danej klasie implementacji:
public SomeReturnType optionalInterfaceMethodA(...) {
throw new UnsupportedOperationException();
}
W Javie 7 i wcześniejszych była to tak naprawdę jedyna „metoda opcjonalna”, która istniała, tj. Metoda, która, jeśli nie została zaimplementowana, zgłosiła wyjątek UnsupportedOperationException. To zachowanie jest koniecznie określone w kontrakcie interfejsu (np. Opcjonalne metody interfejsu Java Collections Framework).
2. Metoda domyślna, której ponowna implementacja jest opcjonalna
Java 8 wprowadziła koncepcję metod domyślnych . Są to metody, których implementacja może być i jest zapewniana przez samą definicję interfejsu. Generalnie możliwe jest udostępnienie metod domyślnych tylko wtedy, gdy treść metody może być napisana przy użyciu innych metod interfejsu (tj. „Prymitywów”) i kiedythis może oznaczać „ten obiekt, którego klasa zaimplementowała ten interfejs”.
Metoda domyślna musi spełniać kontrakt interfejsu (tak jak każda inna implementacja metody interfejsu). Dlatego określenie implementacji metody interfejsu w klasie implementującej jest w gestii autora (o ile zachowanie jest zgodne z jego przeznaczeniem).
W tym nowym środowisku Java Collections Framework można przepisać jako:
public interface List<E> {
:
:
default public boolean add(E element) {
throw new UnsupportedOperationException();
}
:
:
}
W ten sposób metoda „opcjonalna” add()ma domyślne zachowanie polegające na zgłaszaniu wyjątku UnsupportedOperationException, jeśli klasa implementująca nie zapewnia własnego nowego zachowania, co jest dokładnie tym, co chciałbyś, aby się wydarzyło i jest zgodne z umową dotyczącą List. Jeśli autor pisze klasę, która nie pozwala na dodawanie nowych elementów do implementacji List, implementacjaadd() jest opcjonalna, ponieważ domyślne zachowanie jest dokładnie tym, co jest potrzebne.
W tym przypadku „trzecia instrukcja” powyżej nadal jest prawdziwa, ponieważ metoda została zaimplementowana w samym interfejsie.
3. Metoda zwracająca Optionalwynik
Ostatnim nowym rodzajem metody opcjonalnej jest po prostu metoda, która zwraca Optional. Ta Optionalklasa zapewnia zdecydowanie bardziej zorientowany obiektowo sposób postępowanianull wynikami.
W płynnym stylu programowania, takim jak typowy typowy podczas kodowania za pomocą nowego interfejsu API strumieniowania w języku Java, wynik zerowy w dowolnym momencie powoduje awarię programu z wyjątkiem NullPointerException. PlikOptionalKlasa zapewnia mechanizm zwracania wyników zerowych do kodu klienta w sposób, który umożliwia płynny styl bez powodowania kod klienta do katastrofy.