philippe-dunski

philippe-dunski

Java: sale menteur!

L'autre jour, je discutais avec l'un de mes javaistes d'amis.  Après tout, il y a des gens très bien qui développent en java!

Bien sûr, comme je suis plutôt orienté vers le C++, la discussion n'a pas traîné à dériver sur les avantages comparés de java et de C++.  C'est le coup classique!

Lorsque j'en suis arrivé à discuter de l'héritage multiple, il s'est écrié: "Héritage multiple, bons dieux, quelle horreur!". 

J'ai alors pris un exemple classique : Comment créer une classe TurboGenerateur lorsqu'on dispose d'une classe Turbine et d'une classe Generateur ? Après tout, LSP est parfaitement respecté si l'on décide de faire hériter notre classe TurboGenerateur de Turbine et de Generateur, vu qu'un tel objet est, bel et bien, tout à la fois une turbine et un générateur et que l'on retrouve bel et bien, au niveau de TurboGenerateur, tout ce que l'on trouve aussi bien dans l'une que dans l'autre.

- "Et les interfaces, c'est fait pour les cochons? m'a-t-il répondu."

- "Bien sur que non, mais si on a deux développeur -- l'un qui décide de mettre l'accent sur l'aspect Turbine, implémentant également l'interface IGenerateur et l'autre qui décide de mettre l'accent sur l'aspect Generateur, implémentant également  l'interface ITurbine-- on fait quoi?" lui demandai-je. "On se retrouve avec deux classes totalement différentes, qui font exactement la même chose, mais qu'on ne peut pas substituer l'une à l'autre?"

Il m'a alors expliqué que, si Turbine implémentait l'interface ITurbine et que Generateur implémentait l'interface IGenerateur, il n'y aurait aucun problème : la substitution pourrait parfaitement se faire aussi bien en transmettant une ITurbine qu'un IGenerateur.  Il a, sur ce point, totalement raison!

Il faut alors se rendre compte que, lorsque vous décidez en java qu'une de vos classe implémente une interface, vous ne faites rien d'autre que de créer une relation d'héritage au termes du LSP.  Bien sur, votre interface ne fait qu'exposer des comportements "à définir dans la classe qui les implémente", mais il n'y a aucune différence -- hormis le mot clé utilisé pour la définir (interface au lieu de class) -- entre une interface et une classe.

Enfin, ce n'est pas tout à fait vrai, dans le sens où vous devrez utiliser le mot clé inherits pour faire hériter votre classe particulière d'une classe donnée et le mot clé implements pour faire en sorte que votre classe particulière implémente une interface donnée.

Mais un fait demeure : il n'y a, conceptuellement parlant, aucune différence aux termes de LSP entre la relation qui unit une classe dérivée à la classe de base déclarée à l'aide du mot clé inherits et la relation qui unit une classe dérivée et l'interface implémentée à l'aide du mot clé implements.

La seule différence qui existe n'est jamais qu'une différence "artificielle" imposée par java au travers des différents mots clé.

La conclusion logique, c'est que java vous ment lorsqu'il vous impose d'éviter l'héritage multiple! Chaque fois que vous décidez de faire hériter une classe d'une autre et de lui faire implémenter une interface, ou chaque fois que vous décidez qu'une classe implémente plusieurs interface, vous ne faites absolument rien d'autre que créer des relations d'héritage multiple!

Amis javaistes, pensez à cela avant de vous lancer dans une diatribe contre l'héritage multiple : vous en êtes très certainement les plus gros utilisateurs.  Votre langage préféré l'a élevé au rang d'institution en créant la notion d'interface. La seule chose, c'est que vous n'en avez peut être pas conscience à cause des mots clés que vous utilisez.



16/01/2014
2 Poster un commentaire

A découvrir aussi


Inscrivez-vous au blog

Soyez prévenu par email des prochaines mises à jour

Rejoignez les 8 autres membres