Qual è l’implementazione “predefinita” del metodo definito in un’interfaccia?

Nell’interfaccia di raccolta ho trovato un metodo chiamato removeIf() che contiene la sua implementazione.

 default boolean removeIf(Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed; } 

Voglio sapere se esiste un modo per definire il corpo del metodo in un’interfaccia?
Qual è la parola chiave default e come funziona?

Java 8 introduce la nuova funzione “Metodo predefinito” o (metodi Defender), che consente allo sviluppatore di aggiungere nuovi metodi alle interfacce senza interrompere l’implementazione esistente di queste interfacce. Fornisce flessibilità per consentire l’implementazione della definizione dell’interfaccia che verrà utilizzata come impostazione predefinita nella situazione in cui una class concreta non riesce a fornire un’implementazione per tale metodo.

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

C’è una domanda comune che le persone chiedono sui metodi predefiniti quando sentono la nuova funzione per la prima volta:

Cosa succede se la class implementa due interfacce e entrambe le interfacce definiscono un metodo predefinito con la stessa firma?

Esempio per illustrare questa situazione:

 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 { } 

Questo codice non riesce a compilare con il seguente risultato:

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

Per risolvere il problema, in Clazz, dobbiamo risolverlo manualmente sovrascrivendo il metodo in conflitto:

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

Ma se volessimo chiamare l’implementazione di default del metodo foo () dall’interfaccia A invece di implementare la nostra.

È ansible fare riferimento a A # foo () come segue:

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

Questi metodi sono chiamati metodi predefiniti. Il metodo predefinito o il metodo Defender è una delle funzionalità appena aggiunte in Java 8.

Verranno utilizzati per consentire a un metodo di interfaccia di fornire un’implementazione utilizzata come predefinita nel caso in cui una class concreta non fornisca un’implementazione per tale metodo.

Quindi, se hai un’interfaccia, con un metodo predefinito:

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

La seguente class è perfettamente valida:

 public class HelloImpl implements Hello { } 

Se si crea un’istanza di HelloImpl :

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

Link utili:

  • Aggiornato Oracle Tutorial
  • Tutto su Java 8
  • Metodi Defender

Ho fatto un po ‘di ricerche e ho trovato il seguente. Spero che questo ti aiuti.

Problema esistente

I normali metodi di interfaccia sono dichiarati come astratti e devono essere definiti nella class che implementa l’interfaccia. Questo “impegna” l’implementatore di class con la responsabilità di implementare ogni metodo dichiarato. Ancora più importante, questo significa anche che l’estensione di un’interfaccia non è ansible dopo la ‘pubblicazione’. Altrimenti, tutti gli implementatori dovrebbero adattare la loro implementazione, interrompendo l’origine dei backward e la compatibilità binaria.

Soluzione adottata in Java 8

Per far fronte a questi problemi, una delle nuove funzionalità di JDK 8 è la possibilità di estendere le interfacce esistenti con metodi predefiniti. I metodi predefiniti non sono solo dichiarati, ma anche definiti nell’interfaccia.

Punti importanti da notare

  1. Gli implementatori possono scegliere di non implementare i metodi predefiniti nella class di implementazione.
  2. Gli implementatori possono ancora sovrascrivere i metodi predefiniti, come i metodi regolari di class non finale possono essere sovrascritti nelle sottoclassi.
  3. Le classi astratte possono anche (ri) dichiarare i metodi predefiniti come astratti, costringendo sottoclassi a reimplementare il metodo (talvolta chiamato ‘ri-astrazione’).