Une interface dans Java est similaire à une classe, mais le corps d’une interface peut inclure niquement des méthodes abstraites et
final
champs (constantes).
Récemment, j'ai vu une question, qui ressemble à ceci
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
Selon la définition de l'interface, seules les méthodes abstraites sont autorisées. Pourquoi me permet-il de compiler le code ci-dessus? Quel est le mot clé default
?
D'autre part, quand j'essayais d'écrire ci-dessous le code, alors il est dit modifier default not allowed here
default class MyClass{
}
au lieu de
class MyClass {
}
Quelqu'un peut-il me dire le but du mot clé default
? Est-ce autorisé uniquement dans une interface? En quoi diffère-t-il de default
(pas de modificateur d'accès)?
C'est une nouvelle fonctionnalité de Java 8 qui permet à interface
de fournir une implémentation. Décrit dans Java 8 JLS-13.5 .6. Déclarations de méthode d’interface qui lit (en partie)
Ajouter une méthode
default
ou changer une méthode deabstract
àdefault
ne rompt pas la compatibilité avec les fichiers binaires préexistants, mais peut entraîner unIncompatibleClassChangeError
un fichier binaire préexistant tente d'appeler la méthode. Cette erreur se produit si le type de qualification,T
, est un sous-type de deux interfaces,I
etJ
, oùI
etJ
déclare une méthodedefault
avec la même signature et le même résultat, et niI
niJ
ne sont une sous-interface de l'autre.
Quoi de neuf dans JDK 8 dit (en partie)
Les méthodes par défaut permettent d'ajouter de nouvelles fonctionnalités aux interfaces des bibliothèques et d'assurer la compatibilité binaire avec le code écrit pour les versions antérieures de ces interfaces.
Des méthodes par défaut ont été ajoutées à Java 8 principalement pour prendre en charge les expressions lambda. Les concepteurs (astucieusement, selon moi) ont décidé de créer la syntaxe lambdas pour la création d'implémentations anonymes d'une interface. Mais lambdas donné ne peut implémenter que une seule méthode, ils seraient limités à des interfaces avec une seule méthode, ce qui constituerait une restriction assez sévère, mais des méthodes par défaut ont été ajoutées pour permettre l’utilisation d’interfaces plus complexes.
Si vous avez besoin de conviction quant à l'affirmation selon laquelle default
a été introduite en raison de lambdas, notez que la proposition de l'homme de paille du projet Lambda, de Mark Reinhold, en 2009, mentionne les "méthodes d'extension". comme une fonctionnalité obligatoire à ajouter pour supporter les lambdas.
Voici un exemple illustrant le concept:
interface Operator {
int operate(int n);
default int inverse(int n) {
return -operate(n);
}
}
public int applyInverse(int n, Operator operator) {
return operator.inverse(n);
}
applyInverse(3, n -> n * n + 7);
Très artificiel, je réalise mais devrait illustrer comment default
soutient les lambdas. Comme inverse
est un défaut, il peut facilement être remplacé par une classe d’implémentation si nécessaire.
Un nouveau concept est introduit dans Java 8 appelé méthodes par défaut. Les méthodes par défaut sont celles qui ont une implémentation par défaut et qui permettent de faire évoluer les interfaces sans rompre le code existant. Voyons un exemple:
public interface SimpleInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements SimpleInterface{
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}
et le résultat est:
Do Some Work implémentation en classe
Implémentation DoSomeOtherWork dans l'interface
Quelque chose a été négligé dans les autres réponses était son rôle dans les annotations. Aussi loin que Java 1.5, le mot clé default
est apparu comme un moyen de fournir une valeur par défaut pour un champ d'annotation.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Processor {
String value() default "AMD";
}
Son utilisation était surchargée avec l'introduction de Java 8) afin de permettre de définir une méthode par défaut dans les interfaces.
Autre chose qui a été négligé: la raison pour laquelle la déclaration default class MyClass {}
est invalide en raison de la façon dont les classes sont déclarées . Aucune disposition dans la langue ne permet à ce mot-clé d'y apparaître. Il apparaît pour déclarations de méthode d'interface , cependant.
La nouvelle fonctionnalité de Java 8 ( méthodes par défaut ) permet à une interface de fournir une implémentation lorsqu'elle est étiquetée avec le default
mot-clé.
Par exemple:
interface Test {
default double getAvg(int avg) {
return avg;
}
}
class Tester implements Test{
//compiles just fine
}
Interface Test utilise le mot-clé default qui permet à l'interface de fournir une implémentation par défaut de la méthode sans avoir à implémenter ces méthodes dans les classes qui utilisent l'interface.
Compatibilité avec les versions antérieures: Imaginez que votre interface soit implémentée par des centaines de classes. La modification de cette interface obligera tous les utilisateurs à implémenter la nouvelle méthode ajoutée, même si pas indispensable pour de nombreuses autres classes qui implémentent votre interface.
Faits et restrictions:
1-Peut uniquement être déclaré dans une interface et non dans une classe ou une classe abstraite.
2-Doit fournir un corps
3-Il n'est pas supposé être public ou abstrait comme d'autres méthodes normales utilisées dans une interface.
Une très bonne explication se trouve dans The Java ™ Tutorials , une partie de l'explication est la suivante:
Prenons un exemple impliquant des fabricants de voitures contrôlées par ordinateur qui publient des interfaces standard décrivant les méthodes pouvant être utilisées pour faire fonctionner leurs voitures. Et si ces constructeurs de voitures contrôlées par ordinateur ajoutaient de nouvelles fonctionnalités, telles que le vol, à leurs voitures? Ces constructeurs devraient spécifier de nouvelles méthodes pour permettre à d’autres sociétés (telles que les fabricants d’instruments de guidage électronique) d’adapter leurs logiciels aux voitures en vol. Où ces constructeurs automobiles déclareraient-ils ces nouvelles méthodes liées au vol? S'ils les ajoutent à leurs interfaces d'origine, les programmeurs qui ont implémenté ces interfaces devront réécrire leurs implémentations. S'ils les ajoutent en tant que méthodes statiques, les programmeurs les considéreraient comme des méthodes utilitaires et non essentielles.
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 versions antérieures de ces interfaces.
Les méthodes par défaut vous permettent d'ajouter de nouvelles fonctionnalités aux interfaces de vos applications. Il peut également être utilisé pour avoir un héritage multiple. En plus des méthodes par défaut, vous pouvez définir des méthodes statiques dans les interfaces. Cela facilite l'organisation des méthodes d'assistance.
Les méthodes par défaut dans une interface nous permettent d'ajouter de nouvelles fonctionnalités sans détruire l'ancien code.
Avant Java 8, si une nouvelle méthode était ajoutée à une interface, toutes les classes d'implémentation de cette interface étaient tenues de remplacer cette nouvelle méthode, même si elles n'utilisaient pas la nouvelle fonctionnalité.
Avec Java 8, nous pouvons ajouter l'implémentation par défaut de la nouvelle méthode en utilisant le mot clé default
avant l'implémentation de la méthode.
Même avec des classes anonymes ou des interfaces fonctionnelles, si nous voyons que du code est réutilisable et que nous ne voulons pas définir la même logique partout dans le code, nous pouvons écrire des implémentations par défaut de celles-ci et les réutiliser.
Exemple
public interface YourInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements YourInterface{
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Main method
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}