La mise en œuvre de deux interfaces dans une classe avec la même méthode. L'interface sur laquelle la méthode est surchargée?
Deux interfaces avec la même méthode, les noms et les signatures. Mais mis en œuvre par une seule classe alors comment le compilateur va identifier la méthode qui est de l'interface?
Ex:
interface A{
int f();
}
interface B{
int f();
}
class Test implements A, B{
public static void main(String... args) throws Exception{
}
@Override
public int f() { //from which interface A or B
return 0;
}
}
Vous devez vous connecter pour publier un commentaire.
Si un type implémente deux interfaces, et chaque
interface
définir une méthode identique signature, alors en effet il n'y a qu'une seule méthode, et ils ne sont pas distinguables. Si, par exemple, les deux méthodes ont contradictoires types de retour, alors il y aura une erreur de compilation. C'est la règle de l'héritage, redéfinition de méthode, de se cacher, et déclarations, et s'applique aussi à de possibles conflits non seulement entre 2 héritéinterface
méthodes, mais également uneinterface
et un superclass
méthode, ou même simplement en raison de conflits de type effacement de génériques.Compatibilité exemple
Voici un exemple où vous avez un
interface Gift
, qui a unpresent()
méthode (comme dans la présentation de cadeaux), et aussi uninterface Guest
, qui a également unpresent()
méthode (comme dans, l'invité est présent et n'est pas nul).Presentable johnny
est à la fois unGift
et unGuest
.L'extrait ci-dessus compile et s'exécute.
Noter que il y a un seul
@Override
nécessaire!!!. C'est parce queGift.present()
etGuest.present()
sont "@Override
-équivalent" (JLS 8.4.2).Ainsi,
johnny
ne dispose que d'une mise en œuvre depresent()
, et il n'a pas d'importance la façon dont vous traitezjohnny
, que ce soit en tant queGift
ou comme unGuest
, il n'y a qu'une seule méthode pour invoquer.Incompatibilité exemple
Voici un exemple où les deux les méthodes héritées ne sont PAS
@Override
-équivalent:Ce réitère encore une fois que d'en hériter, des membres d'un
interface
doit obéir à la règle générale de déclarations de membre. Ici, nous avonsGift
etGuest
définirpresent()
avec les incompatible types de retour: unvoid
l'autreboolean
. Pour la même raison que vous ne pouvez pas unvoid present()
et unboolean present()
dans un type, cet exemple provoque une erreur de compilation.Résumé
Vous pouvez hériter des méthodes qui sont
@Override
équivalent, sous réserve des exigences habituelles de la redéfinition de méthode et de masquage. Depuis qu'ils SONT@Override
équivalent, effectivement il y a une seule méthode à mettre en œuvre, et donc il n'y a rien pour les distinguer/sélectionner à partir.Le compilateur n'a pas à identifier la méthode qui est de l'interface, car une fois qu'ils sont déterminés à être
@Override
équivalent, elles sont de la même méthode.Résoudre les incompatibilités potentielles peut être une tâche délicate, mais c'est une autre question tout à fait.
Références
default
méthodes en Java 8.Foo
etBar
. Fondamentalement, vous avez votre classe implémente une interface, direFoo
, et de fournir unBar asBar()
méthode pour retourner un à l'intérieur de la classe qui implémente le deuxièmeBar
interface. Pas parfait, car votre classe n'est finalement pas un "Bar", mais il pourrait être utile dans certaines circonstances.Cela a été marquée comme un doublon à cette question https://stackoverflow.com/questions/24401064/understanding-and-solving-the-diamond-problems-in-java
Vous avez besoin de Java 8 pour obtenir un héritage multiple problème, mais c'est toujours pas un diamon problème en tant que tel.
JB Nizet des commentaires, vous pouvez résoudre ce problème à mon prépondérante.
Cependant, vous n'avez pas de problème avec
hi()
(pour corriger l'ambiguïté). Par exemple, par la mise en œuvre à compterA.super.hi()
de choisir de l'appliquer de la même manière que A.Autant que le compilateur est concerné, ces deux méthodes sont identiques. Il y aura une mise en œuvre à la fois.
Ce n'est pas un problème si les deux méthodes sont effectivement identiques, en ce qu'ils devraient avoir la même mise en œuvre. Si ils sont contractuellement différents (conformément à la documentation pour chaque interface), vous serez en difficulté.
Il n'y a rien à identifier. Interfaces seulement de proscrire une méthode de nom et la signature. Si les deux interfaces ont une méthode de même nom et de la signature, de la mise en œuvre de la classe peut implémenter deux méthodes d'interface avec une seule méthode concrète.
Toutefois, si le sémantique contrats de les deux la méthode de l'interface sont contradictoires, vous avez à peu près perdue; vous ne pouvez pas mettre en œuvre les deux interfaces dans une seule classe.
Essayer d'implémenter l'interface en tant qu'anonyme.
Comme dans l'interface,nous venons de nous déclarer des méthodes,de la classe de béton qui met en œuvre ces deux interfaces comprenne, c'est qu'il n'existe qu'une seule méthode(comme vous l'avez décrit les deux ont le même nom dans le type de retour). donc, il ne devrait pas être un problème avec elle.Vous serez en mesure de définir la méthode dans la classe de béton.
Mais quand deux interface ont une méthode avec le même nom, mais différents type de retour et vous mettre en œuvre deux méthodes dans la classe de béton:
Veuillez regarder ci-dessous le code:
quand compilateur obtient méthode "public void print()" il regarde d'abord dans InterfaceA et il l'obtient.Mais encore il donne erreur de compilation que le type de retour n'est pas compatible avec la méthode de InterfaceB.
De sorte qu'il se détraque pour le compilateur.
De cette façon, vous ne serez pas en mesure de mettre en œuvre deux interface de disposer d'une méthode de même nom, mais différents type de retour.
Bien si ils sont tous les deux le même, il n'a pas d'importance. Elle met en œuvre tous les deux avec une seule méthode concrète par la méthode de l'interface.