Quelle est la méthode par défaut?
Après la sortie de Java 8, de nouvelles méthodes peuvent être ajoutées à l'interface, mais l'interface peut toujours être compatible avec sa classe d'implémentation. Ceci est très important car la bibliothèque de classe que vous développez peut être largement utilisée par plusieurs développeurs. Avant Java 8, après la publication d'une interface dans la bibliothèque de classe, si une nouvelle méthode était ajoutée à l'interface, les applications qui implémentent cette interface risqueraient de s'écraser à l'aide de la nouvelle version de l'interface.
Avec Java 8, n'y a-t-il pas un tel danger? La réponse est non.
L'ajout d'une méthode par défaut à une interface peut rendre certaines classes d'implémentation indisponibles.
Tout d'abord, regardons les détails de la méthode par défaut.
Dans Java 8, les méthodes d'interfaces peuvent être implémentées (les méthodes statiques de Java 8 peuvent également être implémentées dans les interfaces, mais c'est un autre sujet). La méthode implémentée dans l'interface est appelée la méthode par défaut, qui est identifiée par le mot-clé par défaut comme un modificateur. Lorsqu'une classe implémente une interface, elle peut implémenter des méthodes qui ont été implémentées dans l'interface, mais ce n'est pas nécessaire. Cette classe héritera de la méthode par défaut. C'est pourquoi lorsque l'interface change, la classe d'implémentation n'a pas besoin d'être modifiée.
Qu'en est-il du temps d'hériter davantage?
Les choses se compliquent lorsqu'une classe implémente plus d'une (par exemple, deux) interfaces et que ces interfaces ont la même méthode par défaut. Quelle méthode par défaut la classe hérite-t-elle? Aucun d'eux ne le n'est! Dans ce cas, la classe doit implémenter la méthode par défaut (uniquement) en elle-même (directement ou hériter des classes de niveau supérieur sur l'arborescence).
Il en va de même lorsqu'une interface implémente la méthode par défaut et que l'autre interface déclare la méthode par défaut comme abstraite. Java 8 essaie d'éviter des choses peu claires et de le garder rigoureux. Si une méthode est déclarée dans plusieurs interfaces, toute implémentation par défaut ne sera pas héritée et vous obtiendrez une erreur de compilation.
Cependant, si vous avez compilé votre classe, il n'y aura pas d'erreurs de temps de compilation. À ce stade, Java 8 est incohérent. Il a ses propres raisons, pour diverses raisons. Je ne veux pas expliquer en détail ou en discuter en profondeur ici (parce que: la version a été publiée et la discussion a été trop longue, et cette plate-forme n’a jamais discuté comme ça).
La classe peut fonctionner normalement dans le cas ci-dessus. Cependant, il ne peut pas être recompilé avec des interfaces modifiées, mais il peut toujours fonctionner avec d'anciennes interfaces. Suivant
Lorsque les deux interfaces fournissent des implémentations par défaut à la même méthode, cette méthode ne peut être appelée que si la classe d'implémentation implémente également la méthode par défaut (soit l'implémente directement ou hérite de la classe de niveau supérieur sur l'arborescence pour l'implémentation).
Cependant, cette classe est compatible. Il peut être chargé de nouvelles interfaces, ou même exécutés, tant qu'il n'appelle pas une méthode qui a une implémentation par défaut dans les deux interfaces.
Exemple de code
Pour démontrer l'exemple ci-dessus, j'ai créé un répertoire de test pour C.Java, qui a 3 sous-répertoires ci-dessous, qui sont utilisés pour stocker i1.java et i2.java. Le répertoire de test contient le code source de C.java de la classe C. Le répertoire de base contient l'interface avec la version qui peut être compilée et exécutée. I1 contient la méthode M () implémentée par défaut, et I2 ne contient aucune méthode.
La classe d'implémentation contient la méthode principale, nous pouvons donc l'exécuter dans le test. Il vérifiera s'il existe des paramètres de ligne de commande, afin que nous puissions facilement exécuter des tests qui appellent m () et ne pas appeler m ().
La classe publique C implémente i1, i2 {public static void main (String [] args) {c c = new C (); if (args.length == 0) {cm (); }}} Interface publique i1 {par défaut void m () {System.out.println ("Hello Interface 1"); }} Interface publique I2 {}Utilisez la ligne de commande suivante pour compiler et exécuter:
Javac -cp.: base c.javajava -cp .: Base Chello Interface 1
Le répertoire compatible contient l'interface I2 avec la méthode abstraite m () et l'interface I1 non modifiée.
Interface publique I2 {void m ();}Cela ne peut pas être utilisé pour compiler la classe C:
Javac -Cp .: C.Javac.java:1 compatible: Erreur: C n'est pas abstrait et ne remplace pas la méthode abstraite m () dans la classe C i2public implémente i1, i2 {^ 1 erreurLe message d'erreur est très précis. Parce que nous avons le C.Class obtenu à partir de la compilation précédente, si nous compilons l'interface dans le répertoire compatible, nous obtiendrons toujours deux interfaces qui peuvent exécuter la classe d'implémentation:
javac compatible / i * .javajava -cp .: Interface chello compatible 1
Le troisième répertoire appelé mal, et l'interface I2 contenue définit également la méthode m ():
Interface publique I2 {par défaut void m () {System.out.println ("Hello Interface 2"); }}Nous ne devons jamais nous lasser de le compiler. Bien que la méthode M () soit définie deux fois, la classe d'implémentation peut toujours s'exécuter tant qu'elle n'appelle pas la méthode qui a été définie plusieurs fois, mais tant que nous appelons la méthode M (), elle échouera immédiatement. Voici les paramètres de ligne de commande que nous utilisons:
Javac tort / *. Javajava -cp .: Mauvais C exception dans le thread "Main" java.lang.incompatibleclasschangeError: Méthodes par défaut conflictuelles: i1.m i2.m à cm (c.java) à C.Main (c.java:5) Java -Cp .: Trust C x
en conclusion
Lorsque vous portez la bibliothèque de classe qui ajoute l'implémentation par défaut à l'interface à l'environnement Java 8, il n'y aura généralement pas de problème. C'est au moins ce que pensent les développeurs de la bibliothèque de classe Java8 lors de l'ajout de méthodes par défaut aux classes de collecte. Les applications qui utilisent votre bibliothèque de classe reposent toujours sur la bibliothèque de classe de Java7 sans la méthode par défaut. Lors de l'utilisation et de la modification de plusieurs bibliothèques de classe différentes, il y a de petites chances de conflit. Comment puis-je l'éviter?
Concevez votre bibliothèque de classe comme avant. Ne le prenez pas à la légère lorsque vous pouvez compter sur la méthode par défaut. Ne l'utilisez pas comme absolument nécessaire. Choisissez judicieusement le nom de la méthode pour éviter les conflits avec d'autres interfaces. Nous apprendrons à utiliser cette fonctionnalité pour le développement dans la programmation Java.
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.