web-dev-qa-db-fra.com

Quelle est l'implémentation "par défaut" de la méthode définie dans une interface?

Dans l'interface de collection, j'ai trouvé une méthode appelée removeIf() qui contient son implémentation.

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

Je veux savoir s'il existe un moyen de définir un corps de méthode dans une interface?
Quel est le mot clé default et comment fonctionne-t-il?

90
gifpif

De https://dzone.com/articles/interface-default-methods-Java

Java 8 introduit la nouvelle fonctionnalité "Méthode par défaut" ou (méthodes Defender), qui permet au développeur d’ajouter de nouvelles méthodes aux interfaces sans rompre l’implémentation existante de ces interfaces. Cela offre de la flexibilité pour permettre une implémentation de définition d'interface qui sera utilisée par défaut dans le cas où une classe concrète ne parvient pas à fournir une implémentation pour cette méthode.

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

public class ClassAB implements A {
}

Il y a une question courante que les gens posent à propos des méthodes par défaut lorsqu'ils entendent parler de la nouvelle fonctionnalité pour la première fois:

Que se passe-t-il si la classe implémente deux interfaces et que ces deux interfaces définissent une méthode par défaut avec la même signature?

Exemple pour illustrer cette situation:

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 {

}  

La compilation de ce code échoue avec le résultat suivant:

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

Pour résoudre ce problème, dans Clazz, nous devons le résoudre manuellement en surchargeant la méthode en conflit:

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

Mais que se passe-t-il si nous souhaitons appeler l’implémentation par défaut de la méthode foo () à partir de l’interface A au lieu de la nôtre?.

Il est possible de se référer à A # foo () comme suit:

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

Ces méthodes sont appelées méthodes par défaut. Méthode par défaut ou Méthode Defender est l'un des nouvelles fonctionnalités ajoutées in Java 8.

Ils seront utilisés pour permettre à une méthode d'interface de fournir une implémentation utilisée par défaut dans le cas où une classe concrète ne fournirait pas d'implémentation pour cette méthode.

Donc, si vous avez une interface, avec une méthode par défaut:

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

La classe suivante est parfaitement valide:

public class HelloImpl implements Hello {

}

Si vous créez une instance de HelloImpl:

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

Liens utiles:

49
Rohit Jain

J'ai fait un peu de recherche et j'ai trouvé ce qui suit. J'espère que cela t'aides.

Problème existant

Les méthodes d'interface normales sont déclarées comme étant abstraites et doivent être définies dans la classe qui implémente l'interface. Cela "pèse" sur le responsable de la mise en œuvre de la classe pour qu'il mette en œuvre toutes les méthodes déclarées. Plus important encore, cela signifie également que l'extension d'une interface n'est pas possible après la "publication". Sinon, tous les implémenteurs devraient adapter leur implémentation en supprimant la compatibilité source et la compatibilité binaire.

Solution adoptée dans Java 8

Pour faire face à ces problèmes, l'une des nouvelles fonctionnalités de JDK 8 est la possibilité d'étendre les interfaces existantes avec des méthodes par défaut. Les méthodes par défaut sont non seulement déclarées, mais également définies dans l'interface.

Points importants à noter

  1. Les implémenteurs peuvent choisir de ne pas implémenter les méthodes par défaut lors de l'implémentation de la classe.
  2. Les implémenteurs peuvent toujours remplacer les méthodes par défaut, de la même manière que les méthodes de classe non finales classiques peuvent être remplacées dans des sous-classes.
  3. Les classes abstraites peuvent même (re) déclarer les méthodes par défaut comme abstraites, ce qui oblige les sous-classes à réimplémenter la méthode (parfois appelée "nouvelle abstraction").
17
Aniket Thakur