La mise en œuvre de deux des interfaces avec les deux méthodes par défaut de la même signature dans Java 8
Supposons que je dispose de deux interfaces:
public interface I1
{
default String getGreeting() {
return "Good Morning!";
}
}
public interface I2
{
default String getGreeting() {
return "Good Afternoon!";
}
}
Si je veux mettre en œuvre les deux d'entre eux, quelle mise en œuvre seront utilisées?
public class C1 implements I1, I2
{
public static void main(String[] args)
{
System.out.println(new C1().getGreeting());
}
}
- Que faire Si
I2
s'étendI1
etC1
implémenteI2
!!? Je pense que cela va compiler...ou je me trompe ? - Merci pour la question! J'ai juste essayé: oui, cela va compiler, quel que soit getGreeting() dans I1 est abstrait ou par défaut. Si la méthode de I1 est par défaut, cela signifie que vous pouvez remplacer la valeur par défaut de mise en œuvre de l'interface-intheritance...
- Oui exactement...Ça sera la méthode héritée.
- Voici un article sur les méthodes par Défaut : Java 8 : méthode par Défaut dans l'Interface
Vous devez vous connecter pour publier un commentaire.
C'est une erreur de compilation. Vous ne pouvez pas avoir deux de la mise en œuvre de deux interfaces.
Cependant, il est correct, si vous mettez en œuvre la
getGreeting
méthode dansC1
:Je veux juste ajouter que, même si la méthode de I1 est abstrait, et par défaut dans I2, vous ne pouvez pas mettre en œuvre les deux d'entre eux. Donc, c'est aussi une erreur de compilation:
Ce n'est pas spécifique à la question. Mais, je pense que cela ajoute de la valeur au contexte. Comme un ajout à l' @toni77 réponse, je tiens à ajouter que, par défaut, la méthode peut être appelé à partir d'une mise en œuvre de la classe, comme indiqué ci-dessous. Dans le code ci-dessous, la méthode par défaut
getGreeting()
deinterface I1
est appelé à partir d'une méthode redéfinie:Si une classe implémente 2 interfaces qui ont tous deux une java-8 par défaut de la méthode avec la même signature (comme dans votre exemple), la mise en œuvre de la classe est obligé de remplacer la méthode. La classe pouvez toujours accéder à la méthode par défaut à l'aide de
I1.super.getGreeting();
. Il peut accéder à l'un, l'autre ou les deux ou aucun des deux. Donc la suite serait valide la mise en œuvre de la C1Il y a un cas où cela fonctionne en fait selon les règles de résolution. Si l'une des interfaces s'étend l'un des autres.
À l'aide de l'exemple ci-dessus:
Le résultat serait:
Bon Après-Midi!
Cependant, je crois que cela va être un gros problème. La raison pour laquelle l'ensemble par défaut des interfaces est de permettre à la bibliothèque de développeurs pour faire évoluer les api sans casser les exécutants.
Compréhensible, ils ne permettent pas de méthodes pour compiler sans la structure d'héritage par extension, car un développeur de la bibliothèque pourrait détourner comportement.
Cependant, ce qui a le potentiel d'être un échec. Si une classe implémente deux interfaces qui ne sont pas liés à partir d'une vue hiérarchique, mais à la fois de définir la même méthode par défaut de signature, puis la classe qui étend les deux interfaces ne compilera pas. (comme démontré ci-dessus)
Il est concevable que les deux différents bibliothèque développeurs pourraient décider d'ajouter des méthodes par défaut à des moments différents à l'aide de signatures courantes; en fait, il est probable que cela se produira dans les bibliothèques qui mettent en œuvre des concepts tels que les bibliothèques de mathématiques. Si vous arrive d'être l'désolé âme la mise en œuvre de deux interfaces dans la même classe, vous allez être cassé sur la mise à jour.
Je crois que la règle est que la classe de mise en œuvre de la double méthodes par défaut "doit" remplacer la mise en œuvre.. Le suivant compile et fonctionne très bien...