En quoi l'héritage diffère-t-il du sous-typage?

15

Dans la perspective du langage de programmation, que signifie le sous-typage? J'ai entendu dire que "l'héritage n'est pas un sous-typage". Quelles sont alors les différences entre l'héritage et le sous-typage?

RoboAlex
la source
6
Je me demande si cette question (et d'autres comme elle) pourrait être redirigée vers le nouveau site cs.SE lorsqu'il entrera en version bêta publique?
Suresh Venkat
1
Bienvenue sur cstheory, un site de questions / réponses pour les questions de recherche en informatique théorique (TCS). Votre question ne semble pas être une question de niveau recherche dans TCS. Veuillez consulter la FAQ pour plus d'informations sur ce que cela signifie et des suggestions de sites susceptibles d'accueillir votre question. Enfin, si votre question est fermée pour être hors de portée, et que vous pensez que vous pouvez modifier la question pour en faire une question de niveau recherche, n'hésitez pas à le faire. La fermeture n'est pas permanente et les questions peuvent être rouvertes, consultez la FAQ pour plus d'informations.
Kaveh
3
@UdayReddy: Aucune question n'était pas triviale lors de la première réponse, mais nous devons prendre une décision du point de vue moderne. Le même argument que le vôtre impliquerait que la question sur l'algorithme de Dijkstra est sur le sujet parce que le premier article en parle et rien d'autre.
Tsuyoshi Ito
3
@TsuyoshiIto L'analogie n'est pas appropriée parce que le premier article de Dijkstra a résolu le problème alors que le premier article de Cardelli ici a créé le problème. Pourtant, je comprends votre point de vue que nous ne mesurons pas l'état de l'art sur la base du premier document. Permettez-moi de vous assurer que les différences entre l'héritage et le sous-typage ne représentent pas un problème résolu, et je prévois que la question sera débattue pendant encore 20 ans au moins. Il pourrait être conseillé à la personne qui pose la question de faire des devoirs supplémentaires et de modifier la question pour clarifier les problèmes au niveau de la recherche.
Uday Reddy
3
Dans tous les cas, il est assez facile de pointer l'OP vers l'article du même nom de Cook et al.: Citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.102.8635
Andreas Rossberg

Réponses:

18

[Je n'ai pas longuement réfléchi aux problèmes des systèmes de type orienté objet, mais je dirai ce que je sais pour lancer la discussion.]

Nous disons que est un sous-type de B si toutes les valeurs de type A peuvent être utilisées dans tous les contextes où des valeurs de type B sont attendues. Ou, pour le dire autrement, les valeurs de type A peuvent se "masquer" comme des valeurs de type B.UNEBUNEBUNEB

Si un tel masquage ne pose aucun problème avec la vérification de type, c'est-à-dire que le branchement de valeurs de type où des valeurs de type B sont nécessaires continue à taper la vérification, nous l'appelons "sous-typage structurel" . S'il ne pose aucun problème de comportement, c'est-à-dire qu'un tel bouchage ne modifie pas le comportement attendu, nous l'appelons alors "sous-typage comportemental" . (Le "comportement attendu" devra être formalisé séparément et de nombreuses notions de comportement sont possibles.)UNEB

Le sous-typage structurel n'assure pas le sous-typage comportemental car la structure d'un type peut correspondre pour des raisons accidentelles. Cependant, définir le comportement attendu n'est pas facile. Ainsi, de nombreux langages de programmation utilisent un point intermédiaire, où l'utilisateur doit déclarer quel type est un sous-type dont. C'est ce que l'on appelle le "sous-typage nominal" . Voir la question sur le sous-typage implicite vs explicitepour une discussion de cette question. L'idée est que le programmeur doit assurer le sous-typage comportemental pour tous les sous-types déclarés en utilisant sa propre ingéniosité. La langue ne peut offrir aucune aide. Cependant, tous les sous-types déclarés doivent être au moins des sous-types structurels. Sinon, le programme ne parviendrait pas à taper check. La langue peut aider à garantir cela. (Certains langages de programmation ne disposent pas de systèmes de type suffisamment bons pour garantir cela au moment de la compilation. Si tel est le cas, l'échec de type serait détecté au moment de l'exécution, ou des résultats erronés pourraient être produits. De tels trous de type ne sont évidemment pas souhaitables.)

Quand on définit des sous-classes dans des programmes orientés objet, on ajoute généralement des champs (ou méthodes) publiquement visibles. Dans la plupart des langages de programmation, ces sous-classes sont considérées comme des sous - types nominaux . La question est de savoir si ce sont également des sous-types structurels . S'ils ne le sont pas, c'est-à-dire que le langage de programmation permet de déclarer des sous-types nominaux qui ne sont pas des sous-types structurels, alors il y aurait des trous de type dans le langage de programmation.

Dans les cas simples, l'ajout de champs fonctionne correctement. Le type de la superclasse attend moins de champs que le type de la sous-classe. Donc, si vous branchez une instance d'une sous-classe où une instance de la sueprclass est attendue, le programme ignorera simplement les champs supplémentaires fournis et rien ne va mal.

Cependant, si la superclasse ou la sous-classe possède des méthodes qui acceptent des arguments du même type que lui-même ou renvoient des résultats du même type que lui-même, des problèmes se posent. Le type d'interface de la sous-classe n'est alors pas un sous-type structurel de celui de la superclasse. Les langages de programmation de type sûr largement utilisés tels que Java n'autorisent pas de telles sous-classes. Ainsi, ils restreignent la langue pour obtenir la sécurité des types. Le langage de programmation Eiffel aurait sacrifié la sécurité de type pour obtenir de la flexibilité à la place. Si l'on conçoit un système de type solide qui conserve sa flexibilité, il faut renoncer au principe selon lequel les sous-classes donnent naissance à des sous-types. D'où le titre de l'article "L'hérédité n'est pas un sous-typage". Les auteurs proposent une notion différente de sous-typage d'ordre supérieur qui fonctionne à la place. Kim Bruce a également une proposition étroitement liée appelée "appariement" qui produit le même effet. Voir cette présentation . Un document de position d'Andrew Black est également utile .

La communauté sémantique est probablement en faute d'avoir largement ignoré le problème. Nous l'avons traditionnellement considéré comme un problème pratique d'ingénierie des systèmes de types qui présente peu d'intérêt théorique. Si ce n'est pas le cas et qu'il y a effectivement du travail sémantique dans le domaine, j'espère que les autres personnes les mentionneront.

Uday Reddy
la source
1
Il convient peut-être également de mentionner qu'il existe de véritables langages qui ont réussi à découpler le sous-typage de l'héritage, par exemple Ocaml dans son système d'objets.
Andreas Rossberg
@AndreasRossberg En effet, OCaml n'était pas dans mon cadre lorsque j'ai écrit cette réponse. Je suppose qu'OCaml n'a pas du tout de sous-typage nominal. Ainsi, certains de ces problèmes ne se poseraient pas. Mais il est possible que les types correspondent accidentellement, même si le comportement ne le fait pas, et le système de type ne pourra pas aider à détecter les erreurs de ce type.
Uday Reddy