Differenza tra metodi statici e predefiniti nell'interfaccia


107

Stavo imparando attraverso le interfacce quando ho notato che ora puoi definire metodi statici e predefiniti in un'interfaccia.

public interface interfacesample2 {
    public static void method() {
        System.out.println("hello world");
    }

    public default void menthod3() {
        System.out.println("default print");
    }
}

Spiega gentilmente la differenza dei due e anche se c'è un esempio di quando lo useremmo sarebbe carino. Un po 'confuso sulle interfacce.


4
Hai provato a leggere i metodi statici nel tutorial Java?
Dawood ibn Kareem

1
Quindi ti sei perso la parte di non essere mai in grado di sovrascrivere un metodo statico?
Dawood ibn Kareem

1
non ho capito lo stesso sulle interfacce
Vipin Menon

9
il metodo statico è un membro statico dell'interfaccia, non può essere sovrascritto (come con la classe), il metodo predefinito è quello default implementationdi un metodo che potrebbe essere sovrascritto.
Shail016

2
Mi chiedo solo: perché non hai mai accettato una risposta qui?
GhostCat

Risposte:


116

Differenze tra metodi statici e predefiniti in Java 8:

1) I metodi predefiniti possono essere sovrascritti nella classe di implementazione, mentre static no .

2) Il metodo statico appartiene solo alla classe Interface, quindi è possibile invocare il metodo statico solo sulla classe Interface, non sulla classe che implementa questa interfaccia, vedere:

public interface MyInterface {
    default void defaultMethod(){
        System.out.println("Default");
    }

    static void staticMethod(){
        System.out.println("Static");
    }    
}

public class MyClass implements MyInterface {

    public static void main(String[] args) {

        MyClass.staticMethod(); //not valid - static method may be invoked on containing interface class only
        MyInterface.staticMethod(); //valid
    }
}

3) Sia la classe che l'interfaccia possono avere metodi statici con lo stesso nome e nessuno dei due sovrascrive altri!

public class MyClass implements MyInterface {

    public static void main(String[] args) {

        //both are valid and have different behaviour
        MyClass.staticMethod();
        MyInterface.staticMethod();
    }

    static void staticMethod(){
        System.out.println("another static..");
    }
}

2
ma perché "statico"? a cosa serve in Java 8?
Shashank Vivek

4
Lo scopo della parola chiave statica non è cambiato: definire i membri a livello di classe: campi, metodi, ecc. In Java 8 questo comportamento è stato esteso alle interfacce, quindi diventano più simili alle classi e ora possono sostituire la classe nella maggior parte degli scenari.
Stinger

sì, ma possiamo ancora nascondere il metodo statico dell'interfaccia invece di sovrascriverlo, .... penso solo che entrambi soddisfano lo stesso purpose( usa un'implementazione comune ) e risolvono l'ambiguità implementing the logic again in subclass ( sovrascrivendo, nascondendo ). l'unica ragione sensata sarebbe dovuta al motivo per cui [i metodi dell'interfaccia statica non sono ereditati] ( stackoverflow.com/questions/25169175/… ) e quindi non possiamo chiamarli utilizzando l'istanza di sottoclasse.
amarnath harish

29

Un metodo statico è un metodo che si applica allo "spazio dei nomi" della classe, per così dire. Quindi un staticmetodo foodi interfaccia Interfaceè accessibile da Interface.foo(). Notare che la chiamata alla funzione non si applica a nessuna particolare istanza dell'interfaccia.

Un'implementazione predefinita bard'altra parte, è chiamata da

Interface x = new ConcreteClass();
x.bar();

Un staticmetodo di interfaccia non può conoscere la thisvariabile, ma un'implementazione predefinita sì.


19

1. spiegare la differenza dei due

I metodi di interfaccia statica sono come i metodi di classe statica (qui appartengono solo all'interfaccia). Dove come i metodi di interfaccia predefiniti forniscono metodi default implementationdi interfaccia (che possono essere le classi di implementazione override)
Ma ricorda che nel caso in cui una classe sia la implementing more than one interface with same defaultfirma del metodo, allora la classe di implementazioneneeds to override the default method

Di seguito puoi trovare un semplice esempio (puoi fare il fai-da-te per casi diversi)

public class Test {
    public static void main(String[] args) {
        // Accessing the static member
        I1.hello();

        // Anonymous class Not overriding the default method
        I1 t = new I1() {
            @Override
            public void test() {
                System.out.println("Anonymous test");
            }
        };
        t.test();
        t.hello("uvw");

        // Referring to class instance with overridden default method
        I1 t1 = new Test2();
        t1.test();
        t1.hello("xyz");

    }
}

interface I1 {

    void test();
    //static method
    static void hello() {
        System.out.println("hello from Interface I1");
    }

    // default need not to be implemented by implementing class
    default void hello(String name) {
        System.out.println("Hello " + name);
    }
}

class Test2 implements I1 {
    @Override
    public void test() {
        System.out.println("testing 1234...");
    }

    @Override
    public void hello(String name) {
        System.out.println("bonjour" + name);
    }
}

2. quando lo useremmo sarebbe bello.

Dipende dalla tua dichiarazione del problema. Direi che i metodi predefiniti sono utili, se hai bisogno della stessa implementazione per un metodo nella tua specifica in tutte le classi in quel contratto, oppure può essere usato come Adapterclassi.

ecco una buona lettura: /software/233053/why-were-default-and-static-methods-added-to-interfaces-in-java-8-when-we-alread

anche sotto il documento Oracle spiega i metodi predefiniti e statici per l'evoluzione delle interfacce esistenti:

Gli utenti che dispongono di classi che implementano interfacce migliorate con nuovi metodi predefiniti o statici non devono modificarle o ricompilarle per accogliere i metodi aggiuntivi.

http://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html


Ho un dubbio. È possibile creare un oggetto di un'interfaccia? Il tuo codice ha questa riga: I1 t = new I1 ()
Hackinet

@ Hackinet ha gentilmente letto il commento java su quella dichiarazione. Leggi anche le lezioni anonime. Spero che ti aiuti.
Shail016

12

Ecco la mia opinione:

metodo statico nell'interfaccia:

  • Puoi chiamarlo direttamente (InterfacetA.staticMethod ())

  • La sottoclasse non potrà eseguire l'override.

  • La sottoclasse può avere un metodo con lo stesso nome di staticMethod

metodo predefinito nell'interfaccia:

  • Non puoi chiamarlo direttamente.

  • La sottoclasse sarà in grado di sovrascriverlo

Vantaggio:

  • Metodo statico: non è necessario creare una classe separata per il metodo di utilità.

  • Metodo predefinito: fornisce la funzionalità comune nel metodo predefinito.


8

Questo collegamento contiene alcune informazioni utili, ne ho elencate alcune qui.

metodi predefiniti e statici hanno colmato le differenze tra interfacce e classi astratte .

Metodi predefiniti dell'interfaccia :

  • Aiuta ad evitare le classi di utilità, come tutto il metodo della classe Collections può essere fornito nelle interfacce stesse.
  • Aiuta ad estendere le interfacce senza avere la paura di rompere le classi di implementazione.

Metodi statici dell'interfaccia :

  • Fanno parte dell'interfaccia, non possiamo usarli per gli oggetti della classe di implementazione.
  • Aiuta a fornire sicurezza non consentendo alle classi di implementazione di sovrascriverle.

Mi piace citare un altro utile riferimento .


3

Metodi predefiniti dell'interfaccia:

Aiuta ad evitare le classi di utilità, come tutto il metodo della classe Collections può essere fornito nelle interfacce stesse.

Aiuta ad estendere le interfacce senza avere la paura di rompere le classi di implementazione.

Metodi statici dell'interfaccia:

Fanno parte dell'interfaccia, non possiamo usarli per gli oggetti della classe di implementazione.

Aiuta a fornire sicurezza non consentendo alle classi di implementazione di sovrascriverle.

Ora come metodo statico che fornisce sicurezza. Vediamo un esempio.

interface MyInterface {
    /*
     * This is a default method so we need not to implement this method in the implementation classes
     */
    default void newMethod() {
        System.out.println("Newly added default method in Interface");
    }

    /*
     * This is a static method. Static method in interface is similar to default method except that we cannot override them in the implementation classes. Similar to default methods, we need to implement these methods in implementation classes so we can safely add them to the existing interfaces.
     */
    static void anotherNewMethod() {
        System.out.println("Newly added static method in Interface");
    }

    /*
     * Already existing public and abstract method We must need to implement this method in implementation classes.
     */
    void existingMethod(String str);
}

public class Example implements MyInterface {
    // implementing abstract method
    public void existingMethod(String str) {
        System.out.println("String is: " + str);
    }

    public void newMethod() {
        System.out.println("Newly added default method in Class");
    }

    static void anotherNewMethod() {
        System.out.println("Newly added static method in Class");
    }

    public static void main(String[] args) {
        Example obj = new Example();

        // calling the default method of class
        obj.newMethod();
        // calling the static method of class

        obj.anotherNewMethod();

        // calling the static method of interface
        MyInterface.anotherNewMethod();

        // calling the abstract method of interface
        obj.existingMethod("Java 8 is easy to learn");

    }
}

Qui obj.newMethod();stampare la logica di implementazione della classe, significa che possiamo cambiare la logica di quel metodo all'interno della classe di implementazione.

Ma obj.anotherNewMethod();stampa la logica di implementazione della classe, ma non è cambiata l'implementazione dell'interfaccia. Quindi, se una logica di crittografia-decrittografia scritta all'interno di quel metodo non può essere modificata.


questa risposta sembra che stia andando da qualche parte bene, poi improvvisamente boom! nessuna spiegazione significativa alla fine. ma non è cambiata l'implementazione dell'interfaccia cosa significa?
amarnath harish

2

Secondo Javadoc di Oracle: http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

I metodi predefiniti consentono di aggiungere nuove funzionalità alle interfacce delle librerie e garantire la compatibilità binaria con il codice scritto per le versioni precedenti di tali interfacce.

Un metodo statico è un metodo associato alla classe in cui è definito piuttosto che a qualsiasi oggetto. Ogni istanza della classe condivide i suoi metodi statici.

Normalmente, il metodo statico nell'interfaccia viene utilizzato come metodi di supporto mentre il metodo predefinito viene utilizzato come implementazione predefinita per le classi che implementano tale interfaccia.

Esempio:

interface IDemo {

    //this method can be called directly from anywhere this interface is visible
    static int convertStrToInt(String numStr) {
       return Integer.parseInt(numStr);
    }


    //getNum will be implemented in a class
    int getNum();       

    default String numAsStr() {
       //this.getNum will call the class's implementation
       return Integer.toString(this.getNum());
    }   

}

1

Come per Java14 documento JLS :

Metodo predefinito:

  • È un metodo di istanza dichiarato in un'interfaccia con il modificatore predefinito

  • È accessibile solo dall'istanza della classe di implementazione

  • Il suo corpo è sempre rappresentato da un blocco, che fornisce un'implementazione o un comportamento predefinito per qualsiasi classe di implementazione senza sovrascrivere il metodo

  • Non può mai essere statico o privato

Metodo statico:

  • Può essere richiamato dall'interfaccia senza riferimento a un oggetto particolare, proprio come i metodi statici della classe

  • Il metodo statico può essere privato

  • La classe di implementazione non può accedere al metodo statico

Capiamo con l'aiuto del seguente codice di esempio:

            public interface MyInterface {
        
            private void privateMethod() {
                System.out.println("Hi, this is privateMethod");
            }
        
            private static void staticPrivateMethod() {
                System.out.println("Hi, this is staticPrivateMethod");
            }
        
            static void staticMethod() {
                //privateMethod();    // Non-static method cannot be referenced from a static contex
                System.out.println("Hi, this is staticMethod");
                staticPrivateMethod();
            }
        
            default void defaultMethod() {
                System.out.println("Hi, this is defaultMethod");
            }
        
        }
    
    public class MyInterfaceImpl implements MyInterface{
        public static void main(String[] args) {
    
            MyInterface.staticMethod();
            // myInterface.staticMethod(); // Not allowed
    
            MyInterface myInterface = new MyInterfaceImpl();
            myInterface.defaultMethod();
            // MyInterface.defaultMethod(); // Not allowed
    
        }
    }

0

non possiamo eseguire Interfacesample2.menthod3();perché non è un metodo statico. Per eseguire method3()abbiamo bisogno di un'istanza di Interfacesample2interfaccia.

Si prega di trovare il seguente esempio pratico:

public class Java8Tester {
   public static void main(String args[]){
      // Interfacesample2.menthod3(); Cannot make a static reference to the non-static method menthod3 from the type Interfacesample2

      new Interfacesample2(){ }.menthod3();// so in order to call default method we need an instance of interface

       Interfacesample2.method(); // it
   }
}

interface Interfacesample2 {
    public static void method() {
        System.out.println("hello world");
    }

    public default void menthod3() {
        System.out.println("default print");
    }
}

0

Anche l'avvio dell'interfaccia Java 8 può avere un metodo statico. Come il metodo statico di una classe, il metodo statico di un'interfaccia può essere chiamato utilizzando il nome dell'interfaccia.

Esempio

public interface Calculator {
    int add(int a, int b);
    int subtract(int a, int b);

    default int multiply(int a, int b) {
         throw new RuntimeException("Operation not supported. Upgrade to UltimateCalculator");
    }

    static void display(String value) {
        System.out.println(value);
    }
}

La differenza tra il metodo di interfaccia statico e quello predefinito è che il metodo predefinito supporta l'ereditarietà ma il metodo statico no. Il metodo predefinito può essere sovrascritto nell'ereditarietà dell'interfaccia.

Ecco una buona lettura del metodo predefinito dell'interfaccia e del metodo statico. Metodo predefinito dell'interfaccia in Java 8


0

Tutte buone risposte qui. Vorrei aggiungere un altro utilizzo pratico della funzione statica nell'interfaccia. Il suggerimento viene dal libro - Effective Java, 3a edizione di Joshua Bloch nel Capitolo 2: Creazione e distruzione di oggetti.

Static functions can be used for static factory methods. 

I metodi factory statici sono metodi che restituiscono un oggetto. Funzionano come costruttori. In casi specifici, il metodo factory statico fornisce un codice più leggibile rispetto all'utilizzo del costruttore.

Citando dal libro - Effective Java, 3a edizione di Joshua Bloch

Prima di Java 8, le interfacce non potevano avere metodi statici. Per convenzione, i metodi factory statici per un'interfaccia denominata Type sono stati inseriti in una classe companion non istanziabile (elemento 4) denominata Types.

L'autore fornisce un esempio di collezioni in cui è implementato tale metodo factory statico. Controllando il codice, Josh Bloch può essere visto come il primo autore della classe Collections. Sebbene Collections sia una classe e non un'interfaccia. Ma il concetto è ancora valido.

Ad esempio, il Java Collections Framework ha quarantacinque implementazioni di utilità delle sue interfacce, fornendo raccolte non modificabili, raccolte sincronizzate e simili. Quasi tutte queste implementazioni vengono esportate tramite metodi factory statici in una classe non istanziabile (java.util.Collections). Le classi degli oggetti restituiti sono tutte non pubbliche.

Inoltre, spiega che l'API non è solo più piccola, aiuta con la leggibilità del codice e la facilità dell'API.

Non viene ridotto solo il grosso dell'API, ma il peso concettuale: il numero e la difficoltà dei concetti che i programmatori devono padroneggiare per utilizzare l'API. Il programmatore sa che l'oggetto restituito ha esattamente l'API specificata dalla sua interfaccia, quindi non è necessario leggere la documentazione aggiuntiva della classe per la classe di implementazione.

Ecco uno dei metodi statici della classe java.util.Collections:

public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
    return new UnmodifiableCollection<>(c);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.