Si j'implémente une interface, est-elle appelée héritage?

31

Si ma classe implementspossède une interface, puis-je dire que je suis l'héritage? Je sais que quand une classe une extendsautre classe, c'est l'héritage.

RajeeV VenkaT
la source
7
Le commentaire de Jodrell est tout simplement faux. Implémenter une interface est en effet un héritage, et hériter une interface d'une autre est un héritage. Comment savons nous? En définissant le mot que nous utilisons. L'héritage est la propriété selon laquelle les membres héritables d'un type sont également membres d'un autre type. Selon cette définition, une classe qui implémente une interface a hérité de toutes les méthodes de l'interface; il suffit de regarder la classe et l'interface et vous verrez que dans un programme correct, ils ont les mêmes membres.
Eric Lippert
J'ai décoché et suis parti avec plus de confusion.
RajeeV VenkaT
18
Pour ce que ça vaut, je pense que vous passez beaucoup de temps sur une définition de mot qui ne vous apportera pas beaucoup d'avantages. À la fin de la journée, nous savons tous ce que signifie la mise en œuvre d'une interface, et si elle est considérée comme «héritage» est en grande partie sans importance pour votre travail quotidien.
Robert Harvey
3
Je suis (principalement) d'accord avec Robert. Je pense qu'il est vraiment utile de comprendre les significations techniques précises des mots de jargon tels qu'ils sont utilisés dans divers contextes. Mais Robert a raison de dire qu'il est beaucoup plus avantageux de comprendre l'impact pratique! Comment pouvez-vous utiliser l'héritage pour rendre votre code plus sûr? Plus testable? Plus réutilisable? Plus flexible? Etc. Savoir que les membres des types de base sont également membres de types dérivés est une bonne chose, mais il vaut mieux encore savoir comment l'utiliser efficacement.
Eric Lippert

Réponses:

78

MISE À JOUR: J'ai révisé cette réponse. Un certain nombre de bons points ont été soulevés dans les commentaires qui méritaient d'être cités.

Si ma classe implémente une interface, puis-je dire que je suis l'héritage?

Il n'est pas tout à fait clair ce que vous entendez par "héritage suivant". Posons une question légèrement différente?

Qu'est-ce que l'héritage?

  • Lorsque les membres d'un type X sont considérés comme membres d'un autre type Y, les membres de Y sont héritées de X .
  • Il existe une relation d'héritage entre certains types; c'est-à-dire que pour certains types X et Y, nous disons "Y hérite de X".

Ce sont subtilement différents. C'est malheureux car c'est déroutant.

Quelles confusions naissent généralement de cette distinction subtile?

La confusion peut survenir parce que les gens considèrent l'héritage comme un mécanisme de partage des détails de mise en œuvre. Bien qu'il est un tel mécanisme, ce mécanisme fonctionne en partageant les membres . Ces membres n'ont pas besoin d'implémentations! Comme nous le verrons, ils peuvent être abstraits.

Personnellement, je serais plus heureux si les spécifications Java et C # utilisaient un mot autre que "hérite" pour décrire la relation entre les méthodes d'interface et les classes, pour éviter cette confusion. Mais ils ne le font pas, et nous devons raisonner à partir des spécifications, pas contre eux.

En Java, les membres de l'interface sont-ils hérités par les classes qui les implémentent?

Oui, certains le sont. Voir la section 8.4.8 des spécifications Java, que je cite ici pour votre commodité.

Une classe C hérite de sa superclasse directe et de ses superinterfaces directes toutes les méthodes abstraites et par défaut m pour lesquelles toutes les conditions suivantes sont vraies: [...]

Si vous dites qu'une classe implémente une interface, la classe hérite des méthodes abstraites et par défaut de cette interface . (Bien sûr, j'ai omis les conditions qui suivent; voir la spécification pour plus de détails. En particulier, une classe qui implémente un membre d'une interface n'est pas considérée comme ayant hérité de ce membre. Encore une fois, est-ce déroutant? Oui.)

Disons-nous généralement en Java qu'une classe hérite d'une interface?

Typiquement, nous dirions qu'une classe implémente une interface. Comme indiqué ci-dessus, une classe peut hériter des membres d'une interface et pourtant ne pas être considérée comme héritant de l'interface. Ce qui prête à confusion, oui.

Cette distinction subtile est-elle importante dans le travail quotidien?

Généralement non. Ce type d'analyse étroite de la spécification est plus utile pour les rédacteurs de compilateurs que pour les développeurs métier. Il est plus important de comprendre quand utiliser une interface que d'obtenir une définition précise de "hérite de".

Eric Lippert
la source
4
Je ne peux pas discuter avec une référence canonique. Lorsque les spécifications diffèrent, comme elles le font nécessairement, les termes simples deviennent surchargés sémantiquement et ambiguës hors contexte. La question est étiquetée java, c'est donc la bonne réponse, à moins que l'OP ne signifiait autre javachose :-)
Jodrell
5
Bien que la question soit balisée avec Java, je trouve problématique de citer une spécification de langage pour un terme générique. De nombreuses langues ont des interfaces et leurs spécifications linguistiques peuvent utiliser un terme différent, donc l'utilisation d'un terme spécifique à Java peut être source de confusion lorsque vous parlez aux développeurs qui utilisent X-Lang.
Thomas Owens
5
@ThomasOwens: Je suis d'accord que ce scénario est courant et je suis totalement en désaccord avec votre conclusion. La solution au problème de communication que vous décrivez est d' éduquer toutes les personnes impliquées quant à la signification précise des mots dans le contexte pertinent . Des spécifications existent pour fournir cette clarté; Utilise les!
Eric Lippert
5
Pourquoi la spécification du langage Java aurait-elle le dernier mot ici? La spécification du langage réclame souvent des choses que le "développeur commun" n'est pas d'accord avec la terminologie.
Benjamin Gruenbaum
5
@BenjaminGruenbaum: Je ne le sais pas. Ces développeurs ont tort, et ils ont souvent la responsabilité de "renseigner" les autres sur leurs fausses croyances. Vous ne croiriez pas le nombre de livres de langage de programmation que j'ai dû corriger parce que les auteurs avaient des croyances complètement folles à propos de VB, C #, JavaScript, etc., qui n'étaient en aucune façon correctes. (Jon Skeet n'était pas parmi eux; C # In Depth était correct depuis le début! Je n'ai jamais fait si peu de commentaires sur un livre et j'ai quand même été payé.)
Eric Lippert
26

L'héritage signifie l'écriture d'une nouvelle sous-classe pour une superclasse. Écrire une nouvelle classe sur une interface implémente cette interface. (Et l'écriture d'une nouvelle interface basée sur une ancienne étend cette interface.)

Le seul terme correct qui s'applique aux trois possibilités est le sous - typage . Tous les sous-types ne sont pas une sous-classe.

Kilian Foth
la source
1
Le livre du GoF semble considérer l'héritage d'interface comme un terme approprié pour décrire le sous-typage (Section 1.6 Class versus Interface Inheritance)
gnat
"J'ai déjà assisté à une réunion d'un groupe d'utilisateurs Java où James Gosling (l'inventeur de Java) était le conférencier vedette. Au cours de la mémorable session de questions-réponses, quelqu'un lui a demandé:" Si vous pouviez refaire Java, que changeriez-vous? "" laisser de côté les classes ", a-t-il répondu. Il a expliqué que le véritable problème n'était pas les classes en soi, mais plutôt l'héritage d'implémentation (la relation étend). L'héritage d'interface (la relation implémente) est préférable. Vous devriez éviter l'héritage d'implémentation autant que possible." javaworld.com/article/2073649/core-java/…
ricardoramos
1

Avec les sous - classes , vous

  • hériter de l'état de la superclasse (toutes les variables d'instance, que vous les voyiez ou non)
  • hériter des implémentations réelles (toutes les méthodes non abstraites)

Avec les interfaces , vous remplissez un contrat en implémentant les méthodes déclarées.

C'est la façon classique de voir les choses. Maintenant, avec Java 8, les interfaces deviennent un mélange:

  • vous n'héritez toujours pas de l'état (car les interfaces n'ont toujours pas de variables d'instance)
  • vous pouvez maintenant hériter des implémentations par défaut de l'interface

Est-ce que l'implémentation d'une interface dont toutes les méthodes ont des implémentations par défaut compterait toujours comme «implémenter», ou plutôt comme extension? Je ne pouvais pas le dire. Comme ce cas est assez farfelu (cela a en fait activé le multi-héritage sans état), j'utiliserais toujours «l'héritage» uniquement avec des sous-classes.

Peter Walser
la source