Interfejs w Javie jest podobny do klasy, ale treść interfejsu może zawierać tylko abstrakcyjne metody i
final
pola (stałe).
Niedawno zobaczyłem pytanie, które wygląda tak
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
Zgodnie z definicją interfejsu dozwolone są tylko metody abstrakcyjne . Dlaczego pozwala mi skompilować powyższy kod? Jakie jest default
słowo kluczowe?
Z drugiej strony, gdy próbowałem napisać poniższy kod, to mówi modifier default not allowed here
default class MyClass{
}
zamiast
class MyClass {
}
Czy ktoś może mi powiedzieć, do czego służy default
słowo kluczowe? Czy jest to dozwolone tylko w interfejsie? Czym się różni od default
(brak modyfikatora dostępu)?
Odpowiedzi:
Jest to nowa funkcja w Javie 8, która umożliwia
interface
implementację. Opisane w Javie 8 JLS-13.5.6. Deklaracje metod interfejsu, które czyta (częściowo)Co nowego w JDK 8 mówi (częściowo)
źródło
private
metody.private
metody nie są tak naprawdę częścią interfejsu, ale mogą służyć jako metody pomocnicze dladefault
implementacji lub w ramach stałych inicjatorów. Zauważ, że istnieją one już w Javie 8, ponieważ podczas używania wyrażeń lambda w interfejsachprivate
generowane są metody syntetyczne . Tak więc Java 9 umożliwia korzystanie z tej funkcji również w przypadku zastosowań niesyntetycznych i innych niż lambda…Metody domyślne zostały dodane do języka Java 8 głównie w celu obsługi wyrażeń lambda. Projektanci (moim zdaniem sprytnie) postanowili stworzyć składnię lambd do tworzenia anonimowych implementacji interfejsu. Ale dane lambdy mogą implementować tylko jedną metodę, byłyby ograniczone do interfejsów z jedną metodą, co byłoby dość poważnym ograniczeniem. Zamiast tego dodano metody domyślne, aby umożliwić korzystanie z bardziej złożonych interfejsów.
Jeśli potrzebujesz trochę przekonania do twierdzenia, które
default
zostało wprowadzone z powodu lambd, zwróć uwagę, że propozycja słomianego człowieka Projektu Lambda, autorstwa Marka Reinholda z 2009 r., Wspomina o „metodach rozszerzania” jako obowiązkowej funkcji dodawanej w celu obsługi lambd.Oto przykład demonstrujący tę koncepcję:
interface Operator { int operate(int n); default int inverse(int n) { return -operate(n); } } public int applyInverse(int n, Operator operator) { return operator.inverse(n); } applyInverse(3, n -> n * n + 7);
Zdaję sobie sprawę, że bardzo wymyślne, ale powinienem zilustrować, jak
default
obsługuje lambdy. Ponieważinverse
jest to ustawienie domyślne, w razie potrzeby można je łatwo zastąpić klasą implementującą.źródło
Coś, co zostało przeoczone w innych odpowiedziach, to jej rola w adnotacjach. Już w Javie 1.5
default
słowo kluczowe służyło jako sposób na podanie domyślnej wartości dla pola adnotacji.@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Processor { String value() default "AMD"; }
Użycie było przeciążone wraz z wprowadzeniem Java 8, aby umożliwić zdefiniowanie domyślnej metody w interfejsach.
Coś jeszcze, co zostało przeoczone: powodem, dla którego deklaracja
default class MyClass {}
jest nieważna, jest sposób, w jaki klasy są w ogóle deklarowane . Nie ma przepisu w języku, który umożliwia pojawienie się tego słowa kluczowego. To nie pojawiają się na deklaracji metody interfejsu , choć.źródło
W Javie 8 wprowadzono nową koncepcję zwaną metodami domyślnymi. Metody domyślne to te metody, które mają pewną domyślną implementację i pomagają w rozwijaniu interfejsów bez przerywania istniejącego kodu. Spójrzmy na przykład:
public interface SimpleInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Not required to override to provide an implementation * for doSomeOtherWork. */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
a wynik to:
Implementacja Do Some Work w klasie
DoSomeOtherWork w interfejsie
źródło
Nowa funkcja Java 8 ( metody domyślne ) umożliwia interfejsowi udostępnienie implementacji, gdy zostanie oznaczona
default
słowem kluczowym.Na przykład:
interface Test { default double getAvg(int avg) { return avg; } } class Tester implements Test{ //compiles just fine }
Interface Test używa domyślnego słowa kluczowego, które umożliwia interfejsowi zapewnienie domyślnej implementacji metody bez konieczności implementowania tych metod w klasach korzystających z interfejsu.
Kompatybilność wsteczna: Wyobraź sobie, że twój interfejs jest zaimplementowany przez setki klas, modyfikacja tego interfejsu zmusi wszystkich użytkowników do zaimplementowania nowo dodanej metody, nawet jeśli nie jest to niezbędne dla wielu innych klas, które implementują twój interfejs.
Fakty i ograniczenia:
1-Może być zadeklarowany tylko w interfejsie, a nie w klasie lub klasie abstrakcyjnej.
2-Musi zapewnić ciało
3-Nie zakłada się, że jest to publiczne lub abstrakcyjne, jak inne normalne metody używane w interfejsie.
źródło
Domyślne metody w interfejsie pozwalają nam dodawać nowe funkcje bez łamania starego kodu.
Przed Java 8, jeśli nowa metoda została dodana do interfejsu, wszystkie klasy implementacji tego interfejsu były zobowiązane do przesłonięcia tej nowej metody, nawet jeśli nie używały nowej funkcji.
W Javie 8 możemy dodać domyślną implementację nowej metody, używając
default
słowa kluczowego przed implementacją metody.Nawet w przypadku anonimowych klas lub interfejsów funkcjonalnych, jeśli widzimy, że jakiś kod nadaje się do ponownego wykorzystania i nie chcemy definiować tej samej logiki w każdym miejscu kodu, możemy napisać ich domyślne implementacje i użyć ich ponownie.
Przykład
public interface YourInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements YourInterface{ /* * Not required to override to provide an implementation * for doSomeOtherWork. */ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Main method */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
źródło
Bardzo dobre wyjaśnienie można znaleźć w samouczkach Java ™ , część wyjaśnień jest następująca:
Rozważmy przykład obejmujący producentów samochodów sterowanych komputerowo, którzy publikują interfejsy zgodne ze standardami branżowymi, opisujące metody, które można zastosować do obsługi ich samochodów. A jeśli producenci samochodów sterowanych komputerowo dodadzą do swoich samochodów nowe funkcje, takie jak latanie? Producenci ci musieliby określić nowe metody, aby umożliwić innym firmom (np. Producentom elektronicznych przyrządów naprowadzania) dostosowanie ich oprogramowania do latających samochodów. Gdzie ci producenci samochodów zadeklarowaliby te nowe metody związane z lotem? Jeśli dodają je do swoich oryginalnych interfejsów, wówczas programiści, którzy zaimplementowali te interfejsy, musieliby przepisać swoje implementacje. Gdyby dodali je jako metody statyczne, programiści potraktowaliby je jako metody użytkowe, a nie podstawowe, podstawowe.
Metody domyślne umożliwiają dodawanie nowych funkcji do interfejsów bibliotek i zapewniają zgodność binarną z kodem napisanym dla starszych wersji tych interfejsów.
źródło
Metody domyślne umożliwiają dodawanie nowych funkcji do interfejsów aplikacji. Może również służyć do dziedziczenia wielokrotnego . Oprócz metod domyślnych w interfejsach można definiować metody statyczne. Ułatwia to organizowanie metod pomocniczych
źródło