Si un type implémente deux interfaces, et chacune interfacedéfinit une méthode qui a une signature identique, alors en fait il n'y a qu'une seule méthode, et elles ne sont pas distinguables. Si, par exemple, les deux méthodes ont des types de retour en conflit, ce sera une erreur de compilation. Il s'agit de la règle générale d'héritage, de substitution de méthode, de masquage et de déclarations.Elle s'applique également aux conflits possibles non seulement entre 2 interfaceméthodes héritées , mais aussi à une interfaceet à une super classméthode, ou même aux conflits dus à l'effacement de type de génériques.
Exemple de compatibilité
Voici un exemple où vous avez un interface Gift, qui a une present()méthode (comme dans, présenter des cadeaux), et aussi un interface Guest, qui a également une present()méthode (comme dans, l'invité est présent et non absent).
Presentable johnnyest à la fois un Giftet un Guest.
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { void present(); }
interface Presentable extends Gift, Guest { }
public static void main(String[] args) {
Presentable johnny = new Presentable() {
@Override public void present() {
System.out.println("Heeeereee's Johnny!!!");
}
};
johnny.present(); // "Heeeereee's Johnny!!!"
((Gift) johnny).present(); // "Heeeereee's Johnny!!!"
((Guest) johnny).present(); // "Heeeereee's Johnny!!!"
Gift johnnyAsGift = (Gift) johnny;
johnnyAsGift.present(); // "Heeeereee's Johnny!!!"
Guest johnnyAsGuest = (Guest) johnny;
johnnyAsGuest.present(); // "Heeeereee's Johnny!!!"
}
}
L'extrait ci-dessus se compile et s'exécute.
Notez qu'il n'y en a qu'un seul @Override nécessaire !!! . En effet, Gift.present()et Guest.present()sont " @Overrideéquivalentes" ( JLS 8.4.2 ).
Ainsi, il johnny n'y a qu'une seule implémentation de present(), et peu importe comment vous traitez johnny, que ce soit en tant que Giftou en tant que Guest, il n'y a qu'une seule méthode à invoquer.
Exemple d'incompatibilité
Voici un exemple où les deux méthodes héritées ne sont PAS @Overrideéquivalentes:
public class InterfaceTest {
interface Gift { void present(); }
interface Guest { boolean present(); }
interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
// "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
// both define present(), but with unrelated return types"
}
Cela réitère en outre que l'héritage des membres d'un interfacedoit obéir à la règle générale des déclarations de membres. Ici, nous avons Giftet Guestdéfinissons present()avec des types de retour incompatibles: l'un voidl'autre boolean. Pour la même raison que vous ne pouvez pas utiliser un void present()et un boolean present()dans un type, cet exemple entraîne une erreur de compilation.
Résumé
Vous pouvez hériter de méthodes @Overrideéquivalentes, sous réserve des exigences habituelles de remplacement et de masquage des méthodes. Puisqu'ils SONT @Override équivalents, il n'y a en fait qu'une seule méthode à implémenter, et donc il n'y a rien à distinguer / sélectionner.
Le compilateur n'a pas à identifier quelle méthode est pour quelle interface, car une fois qu'ils sont déterminés comme étant @Overrideéquivalents, ils sont la même méthode.
Résoudre les incompatibilités potentielles peut être une tâche délicate, mais c'est un autre problème.
Références