Un meilleur job mieux payé ?

Deviens chef de projet, développeur, ingénieur, informaticien

Mets à jour ton profil pro

ça m'intéresse

La P.O.O. : L'héritage

La P.O.O. : L'héritage. Création de classes. Instanciation dynamique d'objets. Un peu de théorie.

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

0. Généralisation.

Imaginons que nous devions fabriquer un logiciel qui permet de gérer une bibliothèque. Cette bibliothèque comporte plusieurs types de documents ; des livres, des CDs, ou des DVDs. Une première étude nous emmène à mettre en ouvre les classes suivantes.

http://emmanuel-remy.developpez.com/C++/GeneralisationSpecialisation/cours/Generalisation.gif


Nous remarquons que dans les trois types de documents, un certain nombre de caractéristiques se retrouvent systématiquement.


Afin d'éviter la répétition des éléments constituant chacune des classes, il est préférable de factoriser toutes ces caractéristiques communes pour en faire une nouvelle classe plus généraliste.


En effet, nous pouvons dire que, d'une façon générale, et quel que soit le type de document, il comporte au moins un titre, un auteur, etc. il semble aller de soi, que le nom de cette nouvelle classe générale s'appelle justement  Document.


Il faut ensuite proposer une relation entre les classes afin de montrer la filiation. Par exemple, il faut bien préciser qu'un Livre est aussi un Document.


La généralisation se représente par une flèche qui part de la classe fille vers la classe mère.

Par exemple, Un Livre possède, certes un nombre de page, mais en suivant la flèche indiquée par la relation de généralisation, elle comporte également un nom d'auteur, un titre, une référence.


En fait, la classe Livre hérite de tout ce que possède la classe Document, les attributs comme les méthodes.

Finalement, cela correspond exactement à ce que nous avions avant sans l'héritage, sauf qu'avec cette technique, nous évitons toutes les duplications.

Toutes les caractéristiques communes n'apparaissent plus dans chacune des classes filles, alors qu'elles sont bien présentes implicitement.

http://emmanuel-remy.developpez.com/C++/GeneralisationSpecialisation/cours/factorisation.gif


Dans cet exemple, nous avons un seul niveau d'héritage, mais il est bien entendu possible d'avoir une hiérarchie beaucoup plus développée. D'ailleurs, si nous regardons de plus prêt, nous remarquons que nous pouvons appliquer une nouvelle fois la généralisation en factorisant la durée du support CD et du support DVD.


En fait, il s'agit dans les deux cas d'un support commun appelé Multimédia.

image

I. Classes abstraites

Lorsque nous allons mettre en ouvre notre programme de gestion de bibliothèque, nous allons avoir finalement un certain nombre d'objets relatifs à chacun de ces documents.

Toutefois, si nous regardons de plus près, nous n'aurons, par exemple, aucun objet relatif à la classe Document.

En effet, les objets qui intéressent le bibliothécaire, sont les livres, les CDs et les DVDs.

Déclarer un objet de la classe Document n'aurait pas de sens. Il s'agit d'une abstraction. Cette classe n'existe que pour les classes filles qui elles correspondent à quelque chose de concret.

Nous pouvons d'ailleurs appliquer le même raisonnement à la classe Multimédia. Il est d'ailleurs de notre devoir d'empêcher que ces classes puissent fournir des objets. De telles classes sont appelées abstraites.

Du cout, les classes classiques sont appelées classes concrètes. Nous ne pouvons déclarer des objets que sur des classes concrètes.

image

II. Spécialisation.

Dans la conception des classes, nous pouvons avoir une démarche inverse de la généralisation, c'est-à-dire, cette fois-ci, de partir plutôt de la classe mère pour aboutir ensuite aux classes filles.

Le concept d'héritage constitue l'un des fondements de la programmation orientée objet. En particulier, il est à la base des possibilités de réutilisation des composants logiciels (en l'occurrence de classes). En effet, il vous autorise à définir une nouvelle classe, dite dérivée, à partir d'une classe existante dite de base. La classe dérivée héritera donc des potentialités de la classe de base, tout en lui ajoutant de nouvelles sans remettre en question la classe de base. Il ne sera pas utile de la recompiler, ni même de disposer du programme source correspondant (exception faite de sa déclaration).

Cette technique permet donc de développer de nouveaux outils en se fondant sur un certain acquis, ce qui justifie le terme d'héritage. Comme nous venons de le voir, plusieurs classes peuvent être dérivées de la même classe de base. En outre, l'héritage, n'est pas limité à un seul niveau : une classe dérivée peut devenir à son tour classe de base pour une autre classe. Nous voyons apparaître la notion d'héritage comme outil de spécialisation croissante.

Par exemple, imaginons que nous disposions déjà d'une classe concrète Personne. Nous pouvons alors spécialiser cette classe afin d'obtenir une classe Elève qui reste bien entendu une personne mais qui possède en plus un certain nombre de spécificités comme, par exemple, la gestion des notes. Dans cet exemple, vous remarquez d'ailleurs que les deux classes sont des classes concrètes.

image

III. La pratique.

Maintenant que les points théoriques sont posés, passons à la pratique.


Créez un nouveau projet nommé TpObjet8-4 sans analyse. Nous allons faire les classes correspondantes à ce diagramme des classes UML :

images de l'éditeur\tp84-1.jpg


Puisque les classes livre, dvd, et cd héritent de document, nous allons commencer par définir Document.

images de l'éditeur\tp84-2.jpg


Document est la classe mère, c'est donc elle qui factorise les méthodes communes. Remarquez la méthode Init, elle remplacera la définition du constructeur dans toutes les classes dérivées, vous voyez le gain qu'apporte la Poo ?


Voici Livre, que du classique (des accesseurs, des mutateurs..):

images de l'éditeur\tp84-3.jpg


Cd :

images de l'éditeur\tp84-4.jpg

Dvd :

images de l'éditeur\tp84-5.jpg


Voici la seule et unique fenêtre du projet :

images de l'éditeur\tp84-6.jpg


La même avec les noms des champs qui la composent :

images de l'éditeur\tp84-7.jpg


Passons au code de la fenêtre :


Les objets seront des objets dynamiques déclarés global à la fenêtre :

images de l'éditeur\tp84-8.jpg


Voici le code du bouton Créer de la zone livre :

images de l'éditeur\tp84-9.jpg


Comme vous le voyez liv1 utilise la méthode Init définie précédemment dans la classe document et agit sur les attributs auteur, titre et référence. Comme tout est hérité init, auteur, titre, référence appartiennent bien à livre, nous n'avons pas eu besoin de les réécrire, magique !


Voici le code du bouton Afficher les informations de la zone livre :

images de l'éditeur\tp84-10.jpg


Voici le code du bouton Créer de la zone Cd :

images de l'éditeur\tp84-11.jpg


Voici le code du bouton Afficher les informations de la zone Cd :

images de l'éditeur\tp84-12.jpg


Voici le code du bouton Créer de la zone Dvd :

images de l'éditeur\tp84-13.jpg


Voici le code du bouton Afficher les informations de la zone Dvd :

images de l'éditeur\tp84-14.jpg


Voilà, c'est fini, je vous laisse remplir les champs, cliquer et observer les comportements. Je pense que vous devriez être séduit par l'élégance de la Programmation Orientée Objet.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2008 Jean Luc Baptiste. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.