2013-08-17 10 views
84

W interfejsie kolekcji znalazłem metodę o nazwie removeIf(), która zawiera jej implementację.Co to jest "domyślna" implementacja metody zdefiniowanej w interfejsie?

Chcę wiedzieć, czy istnieje jakiś sposób zdefiniowania treści metody w interfejsie?
Co to jest słowo kluczowe default i jak ono działa?

+3

zobaczyć ten post o domyślny http://zeroturnaround.com/rebellabs/java-8-explained-default-methods/ #!/ – emeraldjava

+0

Powiązany post https://stackoverflow.com/questions/31578427/what-is-the- purpose-of-the-default-keyword-in-java – Ravi

Odpowiedz

141

Java 8 wprowadza nową metodę "Metody domyślnej" lub (metody Defender), która umożliwia programistom dodawanie nowych metod do interfejsów bez przerywania dotychczasowej implementacji tych interfejsów. Zapewnia elastyczność pozwalającą implementować definicję interfejsu, która będzie używana jako domyślna w sytuacji, gdy konkretna klasa nie zapewni implementacji dla tej metody.

public interface A { 
    default void foo(){ 
     System.out.println("Calling A.foo()"); 
    } 
} 

public class ClassAB implements A { 
} 

Jest jeden wspólny pytanie, które ludzie pytają o metodach domyślnych, gdy słyszą o nowej funkcji po raz pierwszy:

Co jeśli klasa implementuje dwa interfejsy i oba te interfejsy zdefiniowania domyślnego metoda z tym samym podpisem?

przykład ilustrujący tę sytuację:

public interface A { 
    default void foo(){ 
     System.out.println("Calling A.foo()"); 
    } 
} 

public interface B { 
    default void foo(){ 
     System.out.println("Calling B.foo()"); 
    } 
} 


public class ClassAB implements A, B { 

} 

Ten kod nie skompilować z następującym wynikiem:

java: class Clazz inherits unrelated defaults for foo() from types A and B 

to naprawić, w Clazz, musimy go rozwiązać ręcznie przez przesłanianie sprzecznej metody:

public class Clazz implements A, B { 
    public void foo(){} 
} 

Ale co jeśli chcielibyśmy nazwać domyślną implementację metody foo() z interfejsu A zamiast implementacji własnej.

Jest to możliwe w odniesieniu do A # foo() w następujący sposób:

public class Clazz implements A, B { 
    public void foo(){ 
     A.super.foo(); 
    } 
} 
+14

Dzięki, naprawdę dobra ekspozycja. Odpowiedziałeś na wszystkie moje pytania, zanim zdążyłam je zadać. –

+1

Bardzo ładne wyjaśnienie. Dziękuję Ci bardzo. – user2045474

+0

dlaczego nie używać abstrakcji zamiast? –

48

Metody te są nazywane metodami domyślnymi. domyślna metoda lub Defender metoda jest jednym z newly added features w Javie 8.

Będą one wykorzystywane w celu umożliwienia metodę interfejsu, aby zapewnić realizację używany jako domyślny w przypadku gdy beton klasy nie zapewnia wdrożenie dla tej metody.

Tak więc, jeśli masz interfejs, z domyślną metodę:

public interface Hello { 
    default void sayHello() { 
     System.out.println("Hello"); 
    } 
} 

Poniższa klasa jest całkowicie poprawny:

public class HelloImpl implements Hello { 

} 

Jeśli utworzyć instancję HelloImpl:

Hello hello = new HelloImpl(); 
hello.sayHello(); // This will invoke the default method in interface 

Przydatne linki:

+0

Więc jest dobrze, jeśli klasa implementuje interfejs, a nie zaimplementować swoją metodę? Jeśli chodzi o Java7, którego używam, nie jest to dozwolone. –

+2

@AniketThakur. Jest to niedozwolone przed Java 8. Ta funkcja jest dodawana tylko w Java 8. Możesz uniknąć implementacji * domyślnych * metod w swojej klasie implementacji. –

+0

Świetne od +1 do odpowiedzi :) –

17

Zrobiłem trochę badań i znalazłem następujący. Mam nadzieję że to pomoże.

istniejącego problemu

Zwykłe metody interfejsu są zadeklarowane jako abstrakcyjne i musi być zdefiniowana w klasie implementującej interfejs. To "obciąża" wdrażającego klasę z obowiązkiem wdrożenia każdej deklarowanej metody. Co ważniejsze, oznacza to również, że rozszerzenie interfejsu nie jest możliwe po "publikacji". W przeciwnym razie wszyscy implementatorzy musieliby dostosować swoją implementację, przełamując źródło wstecz i zgodność binarną.

Rozwiązanie przyjęte w Java 8

Aby uporać się z tymi problemami, jeden z nowych funkcji JDK 8 jest możliwość rozszerzenia istniejących interfejsów z metod standardowych. Metody domyślne są nie tylko zadeklarowane, ale również zdefiniowane w interfejsie.

Ważne punkty zauważyć

  1. Realizatorzy mogą wybierać nie do wdrożenia metod domyślne klasy wykonawczego.
  2. Implementatory mogą nadal zastępować domyślne metody , podobnie jak zwykłe nieklubowe metody klas mogą być nadpisywane w podklasach .
  3. Klasy abstrakcyjne mogą nawet (ponownie) deklarować domyślne metody jako abstrakcyjne, zmuszając podklasy do ponownego zaimplementowania metody (czasami nazywanej "re-abstrakcją").
Powiązane problemy