next up previous
Next: About this document ... Up: Sous-typage Previous: Sous-typage entre fonctions

Relation entre héritage et polymorphisme

Nous avons vu qu'une sous-classes n'est pas toujours un sous-type de sa super-classe. Les méthodes binaires sont un exemple important, car très courant et nécessaire en programmation, où l'identification entre les notions de sous-classe et de sous-type est impossible.

Pourtant, la plupart des langages OO typés statiquement imposent aux sous-classes de produire de sous-types, même dans le cas de méthodes binaires. Une restriction dans ce sens est d'imposer que les types des méthodes ne changent pas lors de l'héritage. Quelques langages dans ce cas sont: $\mbox{C}^{++}$, Object Pascal et Modula. Dans ces langages, on ne pourra pas écrire l'équivalent de la classe colorpoint, ou de la classe vegetarien, avec le typage donné plus haut.

D'autres langages comme Eiffel et O2, admettent la spécialisation des types des méthodes telles que dans colorpoint. De plus, en Eiffel toute sous-classe est considerée comme sous-type de sa super classe. Du coup, les fonction comme breakit sont bien typés, même lors d'un appel à un objet de type colorpoint, et bien sûr, des erreurs peuvent se produire à l'exécution. Clairement, le système de typage d'Eiffel n'est pas sûr. Les versions plus récentes de ces langages insèrent des tests dynamiques dans les programmes.

En Java, le problème est contourné en affaiblissant les règles de typage. Il suffit d'interdire le type de self d'apparaître dans les types des méthodes. Par exemple, la méthode d'égalité dans point aura le type point -> bool et gardera ce type dans la classe des points colorés après héritage. Cet affaiblissement force l'utilisateur à réaliser des coercions explicites (qui peuvent échouer) s'il veut par exemple, comparer deux points colorés. La validité des coercions pouvant être vérifiés pendant le typage, leur échec est prévisible et le système de typage associé est donc sûr. Cependant, les programmes avec méthodes binaires sont plus difficiles à écrire avec ces restrictions.

En Ocaml, le parti pris est différent. La spécialisation co-variante du types des méthodes, comme dans les classes binaires, sont jugées trop importantes pour être exclues des programmes OO. Du coup, il est impossible de garantir qu'une sous-classe soit sous-type de sa super-classe, mais on revanche on peut assurer qu'elles sont en relation d'instantiation polymorphe. Ce qui est suffisant pour réaliser des opérations programmées par ``spécialisation co-variante''.

Par exemple, les classes point et colorpoint avec méthodes binaires d'égalité ont les types suivants en Ocaml:


\begin{displaymath}\begin{array}{lll}
\alpha_{\tt point} & = &
< {\tt getx: in...
...tarrow{\tt bool};
\, {\tt getcolor : string} >
\\
\end{array}\end{displaymath}

mais, le type de equal dans colorpoint n'est pas un sous-type de celui dans point: il est une instance polymorphe de celui-ci. Pour s'en rendre compte, il suffit de substituer dans le le type des points $\alpha_{\tt point}$ par $\alpha_{\tt colorpoint}$ et $\rho$ par (getcolor : string).

L'instantiation polymorphe est plus faible que le sous-typage, mais il est suffisant pour écrire la plupart des programmes. Il permet d'assurer qu'un objet possède les méthodes attendues. De plus, l'instantiation est une relation co-variante: elle change les types (par specialisation) de même manière que les types des classes se spécialisent par héritage.


next up previous
Next: About this document ... Up: Sous-typage Previous: Sous-typage entre fonctions
Maria-Viginia Aponte
2001-04-10