Différence entre les méthodes statiques et par défaut dans l'interface


107

J'apprenais à travers les interfaces lorsque j'ai remarqué que vous pouvez désormais définir des méthodes statiques et par défaut dans une interface.

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

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

Veuillez expliquer la différence des deux et aussi s'il y a un exemple de quand nous l'utiliserions, ce serait bien. Un peu confus sur les interfaces.


4
Avez-vous essayé de lire sur les méthodes statiques dans le didacticiel Java?
Dawood ibn Kareem

1
Vous avez donc manqué la partie sur le fait de ne jamais pouvoir remplacer une méthode statique?
Dawood ibn Kareem

1
n'a pas compris la même chose sur les interfaces
Vipin Menon

9
La méthode statique est un membre statique de l'interface, ne peut pas être remplacée (comme avec la classe), la méthode par défaut est celle default implementationd'une méthode qui peut être remplacée.
Shail016

2
Je me demande simplement: pourquoi n'avez-vous jamais accepté de réponse ici?
GhostCat

Réponses:


116

Différences entre les méthodes statiques et par défaut dans Java 8:

1) Les méthodes par défaut peuvent être remplacées lors de l'implémentation de la classe, tandis que statiques ne peut pas .

2) La méthode statique appartient uniquement à la classe Interface, vous ne pouvez donc appeler la méthode statique que sur la classe Interface, pas sur la classe implémentant cette Interface, voir:

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) La classe et l'interface peuvent avoir des méthodes statiques avec les mêmes noms, et aucune ne remplace les autres!

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
mais pourquoi «statique»? à quoi sert-il dans Java 8?
Shashank Vivek

4
Le but du mot-clé static n'a pas changé - pour définir les membres au niveau de la classe: champs, méthodes, etc. Dans Java 8, ce comportement a été étendu aux interfaces, de sorte qu'elles deviennent plus similaires aux classes et peuvent maintenant remplacer la classe dans la plupart des scénarios.
stinger

oui mais nous pouvons toujours cacher la méthode statique de l'interface au lieu de la surcharger, .... je pense juste que les deux remplissent la même chose purpose( utilisez une implémentation commune ) et résout l'ambiguïté en implementing the logic again in subclass ( écrasant, masquant ). la seule raison raisonnable serait due à la raison pour laquelle [les méthodes d'interface statiques ne sont pas héritées] ( stackoverflow.com/questions/25169175/… ) et donc nous ne pouvons pas les appeler en utilisant une instance de sous-classe.
amarnath harish

29

Une méthode statique est une méthode qui s'applique à la classe «namespace», pour ainsi dire. On accède donc à une staticméthode food'interface Interfacepar Interface.foo(). Notez que l'appel de fonction ne s'applique à aucune instance particulière de l'interface.

Une implémentation par défaut bar, d'autre part, est appelée par

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

Une staticméthode d'interface ne peut pas connaître la thisvariable, mais une implémentation par défaut le peut.


19

1. expliquer la différence des deux

Les méthodes d'interface statiques sont comme les méthodes de classe statiques (ici elles appartiennent uniquement à Interface). Où, par défaut, les méthodes d'interface fournissent default implementationdes méthodes d'interface (quelles classes d'implémentation peuvent override)
Mais rappelez-vous si une classe est une implementing more than one interface with same defaultsignature de méthode, alors la classe d'implémentationneeds to override the default method

Vous pouvez trouver un exemple simple ci-dessous (peut bricoler pour différents cas)

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. quand nous utiliserions ce serait bien.

Cela dépend de votre énoncé de problème. Je dirais que les méthodes par défaut sont utiles, si vous avez besoin de la même implémentation pour une méthode de votre spécification dans toutes les classes de ce contrat, ou si elles peuvent être utilisées comme des Adapterclasses.

voici une bonne lecture: /software/233053/why-were-default-and-static-methods-added-to-interfaces-in-java-8-when-we-alread

également ci-dessous oracle doc explique les méthodes par défaut et statiques pour faire évoluer les interfaces existantes:

Les utilisateurs qui ont des classes qui implémentent des interfaces améliorées avec de nouvelles méthodes par défaut ou statiques n'ont pas à les modifier ou à les recompiler pour prendre en charge les méthodes supplémentaires.

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


J'ai un doute. Est-il possible de créer un objet d'une interface? Votre code a cette ligne: I1 t = new I1 ()
Hackinet

@Hackinet a bien voulu lire le commentaire java sur cette déclaration. Veuillez également lire sur les classes anonymes. J'espère que cela vous aide.
Shail016

12

Voici mon avis:

méthode statique dans l'interface:

  • Vous pouvez l'appeler directement (InterfacetA.staticMethod ())

  • La sous-classe ne pourra pas passer outre.

  • La sous-classe peut avoir une méthode avec le même nom que staticMethod

méthode par défaut dans l'interface:

  • Vous ne pouvez pas l'appeler directement.

  • La sous-classe pourra la remplacer

Avantage:

  • Méthode statique: vous n'avez pas besoin de créer une classe distincte pour la méthode utilitaire.

  • Méthode par défaut: fournit la fonctionnalité commune dans la méthode par défaut.


8

Ce lien contient des informations utiles, vous en avez répertorié quelques-unes ici.

les méthodes par défaut et statiques ont comblé les différences entre les interfaces et les classes abstraites .

Méthodes par défaut de l' interface :

  • Cela permet d'éviter les classes utilitaires, telles que toutes les méthodes de classe Collections peuvent être fournies dans les interfaces elles-mêmes.
  • Cela aide à étendre les interfaces sans avoir peur de casser les classes d'implémentation.

Méthodes statiques d' interface :

  • Ils font partie de l'interface, nous ne pouvons pas l'utiliser pour les objets de classe d'implémentation.
  • Cela aide à assurer la sécurité en ne permettant pas aux classes d'implémentation de les remplacer.

Je voudrais citer une autre référence utile .


3

Méthodes par défaut de l'interface:

Cela permet d'éviter les classes utilitaires, telles que toutes les méthodes de classe Collections peuvent être fournies dans les interfaces elles-mêmes.

Cela aide à étendre les interfaces sans avoir peur de casser les classes d'implémentation.

Méthodes statiques d'interface:

Ils font partie de l'interface, nous ne pouvons pas l'utiliser pour les objets de classe d'implémentation.

Cela aide à assurer la sécurité en ne permettant pas aux classes d'implémentation de les remplacer.

Maintenant, comment une méthode statique assurant la sécurité. Voyons un exemple.

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");

    }
}

Ici obj.newMethod(); impression de la logique d'implémentation de classe signifie que nous pouvons changer la logique de cette méthode à l'intérieur de la classe d'implémentation.

Mais la obj.anotherNewMethod();logique d'implémentation de classe d'impression, mais pas d'implémentation d'interface modifiée. Donc, si une logique de cryptage-décryptage écrite à l'intérieur de cette méthode, vous ne pouvez pas changer.


cette réponse semble aller quelque part bien ,, puis soudainement boum! aucune explication significative à la fin. mais pas changé la mise en œuvre de l'interface qu'est-ce que cela signifie?
amarnath harish

2

Selon Javadocs d'Oracle: http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

Les méthodes par défaut vous permettent d'ajouter de nouvelles fonctionnalités aux interfaces de vos bibliothèques et d'assurer la compatibilité binaire avec le code écrit pour les anciennes versions de ces interfaces.

Une méthode statique est une méthode associée à la classe dans laquelle elle est définie plutôt qu'à un objet. Chaque instance de la classe partage ses méthodes statiques.

Normalement, la méthode statique dans l'interface est utilisée comme méthodes d'assistance tandis que la méthode par défaut est utilisée comme implémentation par défaut pour les classes qui implémentent cette interface.

Exemple:

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

Conformément à la documentation JLS Java14 :

Méthode par défaut:

  • C'est une méthode d'instance déclarée dans une interface avec le modificateur par défaut

  • Il n'est accessible que par l'instance de la classe d'implémentation

  • Son corps est toujours représenté par un bloc, qui fournit une implémentation ou un comportement par défaut pour toute classe d'implémentation sans remplacer la méthode

  • Cela ne peut jamais être statique ou privé

Méthode statique:

  • Il peut être appelé par l'interface sans référence à un objet particulier, tout comme les méthodes statiques de classe

  • La méthode statique peut être privée

  • La classe d'implémentation ne peut pas accéder à la méthode statique

Comprenons-le à l'aide de l'exemple de code ci-dessous:

            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

nous ne pouvons pas exécuter Interfacesample2.menthod3();car ce n'est pas une méthode statique. Pour exécuter, method3()nous avons besoin d'une instance deInterfacesample2 interface.

Veuillez trouver l'exemple pratique suivant:

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

L'interface de démarrage de Java 8 peut également avoir une méthode statique. Comme la méthode statique d'une classe, la méthode statique d'une interface peut être appelée à l'aide du nom d'interface.

Exemple

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 différence entre la méthode statique et la méthode d'interface par défaut est que la méthode par défaut prend en charge l'héritage, mais pas la méthode statique. La méthode par défaut peut être remplacée dans l'interface d'héritage.

Voici une bonne lecture de la méthode par défaut de l'interface et de la méthode statique. Méthode d'interface par défaut dans Java 8


0

Toutes les bonnes réponses ici. Je voudrais ajouter une autre utilisation pratique de la fonction statique dans l'interface. L'astuce vient du livre - Effective Java, 3e édition de Joshua Bloch dans le chapitre 2: Créer et détruire un objet.

Static functions can be used for static factory methods. 

Les méthodes de fabrique statique sont des méthodes qui retournent un objet. Ils fonctionnent comme constructeur. Dans des cas spécifiques, la méthode de fabrique statique fournit un code plus lisible que l'utilisation du constructeur.

Citation du livre - Effective Java, 3e édition par Joshua Bloch

Avant Java 8, les interfaces ne pouvaient pas avoir de méthodes statiques. Par convention, les méthodes de fabrique statique pour une interface nommée Type ont été placées dans une classe compagnon non instable (élément 4) nommée Types.

L'auteur donne un exemple de collections où une telle méthode de fabrique statique est implémentée. En vérifiant le code, Josh Bloch peut être considéré comme le premier auteur de la classe Collections. Bien que Collections soit une classe et non une interface. Mais le concept s'applique toujours.

Par exemple, le Java Collections Framework a quarante-cinq implémentations utilitaires de ses interfaces, fournissant des collections non modifiables, des collections synchronisées, etc. Presque toutes ces implémentations sont exportées via des méthodes de fabrique statiques dans une classe non instable (java.util.Collections). Les classes des objets retournés sont toutes non publiques.

En outre, il explique que l'API n'est pas seulement plus petite, elle contribue à la lisibilité du code et à la facilité de l'API.

Ce n'est pas seulement l'essentiel de l'API qui est réduit mais le poids conceptuel: le nombre et la difficulté des concepts que les programmeurs doivent maîtriser pour utiliser l'API. Le programmeur sait que l'objet retourné a précisément l'API spécifiée par son interface, il n'est donc pas nécessaire de lire la documentation de classe supplémentaire pour la classe d'implémentation.

Voici l'une des méthodes statiques de la classe java.util.Collections:

public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
    return new UnmodifiableCollection<>(c);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.