Ambiguïté D'héritage Multiple avec Interface
Nous connaissons tous le diamant problème concernant l'héritage multiple -
A
/
B C
/
D
ce problème décrit une situation ambiguë pour la classe D
. Si la classe A
a une méthode et les deux/l'un de B
et/ou C
outrepasser la méthode alors quelle version de la méthode ne D
outrepasser?
ce problème s'applique-t-il aussi aux interfaces en Java? Si non, comment Java les interfaces surmontent ce problème?
5 réponses
le problème de diamant ne s'applique qu'à implémentation héritage ( extends
dans toutes les versions de Java antérieures à Java 8). Il ne s'applique pas à API héritage ( implements
dans toutes les versions de Java antérieures à Java 8).
puisque les méthodes d'interface avec les signatures de type correspondantes sont compatibles, il n'y a pas de problème de diamant si vous héritez de la même signature de méthode deux fois: les signatures de méthode correspondantes se coalesce simplement plutôt. (Et si les signatures de type ne sont pas les mêmes, alors vous n'avez pas le problème de diamant non plus.)
en Java 7 et ci-dessous, le seul moyen d'hériter du code implementation était via le mot-clé extends
, qui se limite au plus un parent. Il n'y a donc pas d'héritage de mise en œuvre multiple et le problème du diamant n'existe pas.
Java 8 ajoute une nouvelle ride car il permet aux interfaces d'avoir une implémentation code. Il échappe toujours au problème du diamant en retombant simplement sur le comportement précédent (aucun héritage d'implémentation) lorsque vous implémentez plusieurs interfaces avec des méthodes qui ont des signatures correspondantes.
pour ajouter aux réponses existantes sur Java8 l'héritage multiple avec interfaces (A. K. A. comment Java évite encore le problème du diamant):
il y a trois règles à suivre:
-
une classe gagne toujours . L'implémentation de la méthode propre à la classe prend la priorité sur les méthodes par défaut dans les Interfaces.
-
si la classe n'en a pas: le le plus spécifique l'interface gagne
- si ce n'est pas le cas, la classe d'héritage doit indiquer explicitement quelle méthode de mise en œuvre il utilise (sinon il ne compilera pas)
Java surmonte ce problème même si les interfaces peuvent avoir des implémentations par défaut des méthodes, parce que l'implémentation par défaut est soit sans ambiguïté (celle de la classe A
) ou la situation est résolue par une règle quelconque (lorsque la classe B
ou la classe C
l'emporte sur l'implémentation de la classe A
, voir ci-dessous).
lorsque les surtypes d'une classe ou d'une interface fournissent plusieurs méthodes par défaut avec la même signature:
- les méthodes D'Instance sont préférées aux méthodes par défaut d'interface. Les méthodes
- qui sont déjà supplantées par d'autres candidats sont ignorées. cette situation peut se produire lorsque les supertypes partagent un ancêtre commun .
cependant, si deux ou plusieurs méthodes par défaut définies de manière indépendante entrent en conflit , ou une méthode par défaut en cas de conflit avec une méthode abstraite, le compilateur Java produit une erreur de compilation. Vous doit explicitement remplacer les méthodes supertype . Dans ce cas, vous pouvez invoquer n'importe laquelle des implémentations par défaut avec le mot-clé super.
avec des méthodes par défaut dans l'interface introduite en Java 8, problème de succession multiple peut se poser, Il ya 3 scénarios -
1-si implémenter class l'emporte sur la méthode par défaut et fournit sa propre fonctionnalité pour la méthode par défaut, alors la méthode de la classe A priorité sur les méthodes par défaut de l'interface.
2-lorsque la classe implémente les deux interfaces et que les deux ont la même méthode par défaut, la classe n'est pas non plus en dépassant cette méthode alors l'erreur sera lancée.
3-dans le cas où une interface étend une autre interface et que les deux ont la même méthode par défaut, la méthode par défaut de l'interface d'héritage aura priorité.
plus d'informations ici .
Java ne supporte pas les héritages multiples, donc le problème du diamant ne se pose pas. Si B & C sont des interfaces, alors il n'y a pas d'implémentation dans les interfaces. Même si B & c outrepasse la méthode dans l'interface A (ne peut pas être une classe), les méthodes auront la même signature. Il n'y a aucune ambiguïté quant à la mise en œuvre à utiliser, car il n'y a pas de mise en œuvre.