- Héritage multiple
-
Certains langages de programmation orientés objets (par exemple C++, Eiffel, Python...) permettent l’héritage multiple, dans lequel une classe peut hériter de comportements et de fonctionnalités de plus d'une super-classe. Au contraire de l'héritage simple, dans lequel une classe hérite d'une unique super-classe.
L'héritage multiple peut poser des problèmes délicats, il y a donc controverse sur le fait de savoir si ses avantages surpassent ses inconvénients. Java a fait le compromis suivant : il permet à une classe d'implémenter des interfaces de plus d'un de ses parents (c’est-à-dire que l'on peut spécifier qu'une classe doit avoir toutes les méthodes exposées à l'extérieur de ses parents d'interface, et permettre au compilateur de s'en assurer), mais elle peut hériter les méthodes et données d'une unique classe parente. Les langages de Microsoft comme C# et Visual Basic implémentent cette même approche.
Le principal problème que pose l'héritage multiple provient d'entités comme une méthode ou un membre qui sont présents plusieurs fois dans les ancêtres d'une classe. Ce cas est appelé problème du diamant. Par exemple si on définit une classe App pour les appareils portables alimentés par une batterie, une classe Tel pour les téléphones portables qui hérite de App, une classe Ord pour les ordinateurs portables qui hérite de App et enfin une classe TelOrd pour les téléphones servant aussi d'ordinateurs qui hérite de Ord et de Tel. Alors on ne sait pas très bien si les instances de TelOrd comportent une ou deux batteries et sous quel nom les différencier. Une solution consiste à rajouter un mécanisme dans le langage pour choisir entre la fusion des entités répétées ou le renommage de celles-ci afin de séparer les entités. Cette solution est implémentée dans Eiffel ou Ocaml pour ne citer que les plus connus. C++ de son côté propose l'héritage virtuel comme outil complémentaire moins ambitieux. La finesse des mécanismes sémantiques mis en jeu dans l'héritage multiple a rebuté beaucoup d'utilisateurs et explique la mauvaise réputation qu'il a acquise dans une partie de la communauté des développeurs.
Un second niveau de problèmes apparaît quand il s'agit de compiler ou d'exécuter des programmes utilisant des classes à héritage multiple. En effet dans le cas d'appel de méthodes polymorphiques (quand une même méthode a plusieurs versions dans des classes héritant les unes des autres), il faut trouver quelle méthode doit être exécutée. Dans le cadre d'un héritage simple, les ancêtres d'une classe forment une liste et il est facile de créer une table de liaison dynamique permettant avec un simple test de trouver la bonne version. Dans le cadre d'un héritage multiple les ancêtres d'une classe forment maintenant un graphe et la table de liaison dynamique est plus difficile à créer. Néanmoins des algorithmes de compilation existent pour cela ; il est ainsi possible de résoudre les héritages multiples avec le même coût à l'exécution que l'héritage simple. Évidemment il est impossible d'utiliser ces techniques avec des langages qui ne sont pas compilés (comme PHP) ; dans ce cas, il faut parcourir le graphe d'héritage pendant l'exécution, ce qui peut être assez long.
Voir aussi
Wikimedia Foundation. 2010.