Si un type implémente deux interfaces, et que chaque interface
définir 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 contradictoires, alors il y aura une erreur de compilation. Il s'agit de la règle générale de l'héritage, de la substitution de méthode, de la dissimulation et des déclarations, et elle s'applique également aux conflits possibles non seulement entre deux méthodes héritées, mais aussi entre les deux méthodes. interface
mais aussi une interface
et un super class
ou même simplement des conflits dus à l'effacement de type des génériques.
Exemple de compatibilité
Voici un exemple où vous avez un interface Gift
qui a une present()
(comme dans la présentation de cadeaux), et également une interface Guest
qui a également un present()
(c'est-à-dire que l'invité est présent et non absent).
Presentable johnny
est à la fois un Gift
et 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 que il n'y a qu'un seul @Override
nécessaire ! !! . Cela s'explique par le fait que Gift.present()
y Guest.present()
sont " @Override
-équivalent" ( JLS 8.4.2 ).
Ainsi, johnny
n'a qu'une seule implémentation de present()
et peu importe la façon dont vous traitez johnny
que ce soit en tant que Gift
ou 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
-équivalent :
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éaffirme que le fait d'hériter de membres d'un interface
doit obéir à la règle générale des déclarations de membres. Ici, nous avons Gift
y Guest
definir present()
avec des types de retour incompatibles : un void
l'autre boolean
. Pour la même raison qu'on ne peut pas faire une void present()
et un boolean present()
dans un seul type, cet exemple donne lieu à une erreur de compilation.
Résumé
Vous pouvez hériter des méthodes qui sont @Override
-sous réserve des exigences habituelles en matière de remplacement et de masquage des méthodes. Puisqu'ils SONT @Override
-En fait, il n'y a qu'une seule méthode à mettre en œuvre, et il n'y a donc rien à distinguer/sélectionner.
Le compilateur n'a pas besoin d'identifier quelle méthode correspond à quelle interface, car une fois qu'il est déterminé qu'il s'agit de @Override
-équivalent, c'est la même méthode.
Résoudre les incompatibilités potentielles peut être une tâche délicate, mais c'est une autre question.
Références