1 L’approche orientée objet Il est difficile de faire l’apprentissage efficace et

1 L’approche orientée objet Il est difficile de faire l’apprentissage efficace et réussi de Java et de C++ sans étudier l’approche orientée objet indépendamment de la syntaxe de ces deux langages. Pour certains principes de cette approche, Java et C++ peuvent d’ailleurs parfois présenter des spécificités. Pour éviter donc d’entrer trop rapidement dans les détails les plus abscons des deux langages, ce chapitre traite de l’orienté objet en général dans un esprit le plus didactique possible. Derrière ces deux langages se cachent les concepts fondamentaux de la programma- tion orientée objet. Dans ce chapitre, nous décrivons l’approche orientée objet sans jamais utiliser une ligne de code. Un dessin valant mieux qu’un long discours, nous proposons quelques figures fondées sur la notation graphique UML (Unified Modeling Language). La connaissance de cette notation n’est en aucun cas néces- saire pour aborder ce chapitre. Cependant, le lecteur peut se référer à [Barbier, 2005] pour d’éventuels approfondissements. Le début de ce chapitre décrit le passage de la dualité type/variable des langages de programmation « classiques » au modèle classe/instance de la programmation objet. Viennent après les fondamentaux de l’orienté objet : l’encapsulation, la différence entre propriétés d’instance et propriétés de classe, l’héritage et le polymorphisme, la généricité et la programmation défensive. Tous ces mécanismes caractérisent l’orienté objet mais ne sont pas exclusifs d’autres mécanismes de programmation plus spécialisés expliqués en détail et en profondeur pour Java et pour C++ dans les autres chapitres. 6 ◆ Conception orientée objet en Java et C++ 1.1 Dualité classe/instance Le couple classe/instance de la programmation objet étend le principe du couple type/variable de la programmation structurée1 (Fortran, COBOL, C, Pascal et bien d’autres langages de programmation) qui a précédé l’orienté objet. Tout comme un type établit les propriétés d’une variable, une classe (une structure de données) est un moule, un gabarit, pour l’instance. L’instance est une incarnation, un exemplaire reproductible à l’envi de sa classe. Imaginons la création d’un logiciel d’éveil pour enfants, dans lequel évoluent des éléphants. Ce jeu fait apparaître à l’écran des éléphants et interroge les utilisateurs sur des propriétés de ces mammifères. Il est immédiatement nécessaire de décrire le type (la classe) Éléphant. En ce sens, à la figure 1.1, l’éléphant est considéré et étudié en tant qu’espèce du règne animal. À la figure 1.2, des instances réelles d’éléphants naissent et meurent au gré de la vie mais respectent invariablement leur appartenance à une branche particulière de la classification animale : celle imagée à la figure 1.1. Une classe Elephant écrite en C++ est ébauchée à la section 2.3.6. 1. La programmation objet étant aussi « structurée », opposer dans l’absolu programmation objet et programmation structurée n’a pas de sens. En fait, nous utilisons le vocabulaire consacré qui veut que l’expression « programmation structurée » désigne souvent ce qui a précédé l’orienté objet. Figure 1.1 • L’espèce (la classe) Éléphant vue sous l’angle zoologique. Figure 1.2 • Des instances (Jumbo à gauche et Babar à droite) de la classe Éléphant. L’approche orientée objet ◆ 7 1.1.1 Abstraction L’abstraction est la faculté de représenter quelque chose incomplètement. La repré- sentation est délibérément réductrice de la chose pour s’affranchir de la complexité inhérente à cette chose. Construire une classe en programmation objet est par défi- nition produire une abstraction. Une entité logicielle est par essence un artefact, un élément artificiel qui imite incom- plètement un concept, une chose physique ou logique, une idée… tous issus d’une « réalité observée ». L’idée-clé des langages à objets a toujours été de fournir un support de description des « choses perçues » en espérant un fossé plus étroit avec le monde réel. Simplement, décrire la classe Éléphant en Java ou C++, c’est restreindre l’espèce des éléphants à quelques propriétés d’intérêt tout en en occultant bien d’autres qu’on ne pourra jamais exhaustivement prendre en compte dans un ordinateur. Ainsi, si je construis un logiciel d’éveil, ma représentation informatique des éléphants se résume, par souci de concision et d’efficacité, à ce que le jeu montre aux enfants : leur couleur, leur corpulence… Ma classe ne décrira pas par exemple leur régime alimen- taire si le jeu n’exploite pas cette propriété. 1.1.2 Pourquoi les classes ? À l’origine de la programmation, les types des variables n’ont pas toujours existé (dans les versions originelles du langage de programmation BASIC par exemple). De façon évidente et rationnelle, il a été nécessaire de contractualiser les usages des diffé- rentes variables en fonction des capacités des ordinateurs (taille maximale d’occupa- tion mémoire des nombres entiers, des nombres décimaux…) et des manipulations- types et récurrentes que faisaient les programmeurs de leurs données. Un entier peut ainsi s’additionner avec un autre entier ; un éléphant peut barrir ou encore avoir une certaine corpulence (mesurer une certaine hauteur…). Les classes sont ainsi constituées de propriétés elles-mêmes typées. Les classes forment de nouveaux types. Il en résulte que chaque instance de la classe Éléphant a une certaine hauteur (valeur de la propriété), le concept de hauteur n’étant pas étranger aux éléphants puisqu’il contribue à définir leur corpulence. L’apport de la programmation objet est de dépasser les simples propriétés statiques comme la hauteur pour s’intéresser aux propriétés dynamiques. Barrir est donc une opération (un traitement) supportée par la classe des éléphants. Au-delà, l’opération barrir peut être paramétrée ; la puissance du barrissement peut ainsi dépendre de la corpulence de l’éléphant en train de barrir, par exemple : •Si corpulence « importante » alors son émis « fort » sinon si corpulence •« moyenne »… L’informatique est fondée sur le principe universel de séparation entre traitements et données. Les paradigmes de programmation exploitent ce principe de façon diffé- rente. Tandis que données et traitements sont pensés plutôt séparément en « approche traditionnelle », avec le paradigme objet, le confinement des traitements 8 ◆ Conception orientée objet en Java et C++ dans la structure de données (la classe) est essentiel. La figure 1.3 illustre ce principe où le type Éléphant se caractérise à la fois par des propriétés statiques, les données (partie haute de la boîte), et dynamiques, les traitements (partie basse de la boîte). Les traitements restent séparés (graphiquement) des données. Cependant, ils ne peuvent pas concerner d’autres structures de données que la classe elle-même comme l’incite la programmation structurée. À l’exécution, les objets informatiques, ceux alloués dans la mémoire de l’ordinateur, sont établis en fonction du format à droite de la figure 1.3. La réalité présentée à la figure 1.2 (Jumbo et Babar) peut donc être « virtualisée » comme montré à la figure 1.4. À la figure 1.4, on voit que Babar barrit moins fort que Jumbo compte tenu de sa moindre corpulence. 1.2 Encapsulation L’encapsulation est un moyen technique de l’orienté objet pour instrumenter l’abstraction. Une partie de la classe est délibérément masquée (ou « encapsulée »), ce qui rend plus aisé l’accès à la classe de l’extérieur. L’intérieur, invisible du côté utilisateur, rend de fait la classe moins complexe à utiliser. Figure 1.3 • Conceptualisation de l’éléphant sous forme d’une classe informatique. Figure 1.4 • Les deux éléphants réels à la figure 1.2 « virtualisés » dans un logiciel. Éléphant hauteur ... barrir ... Jumbo : Éléphant hauteur = 3,70 ... barrir ... Babar : Éléphant hauteur = 3,50 ... barrir ... L’approche orientée objet ◆ 9 Cette idée s’applique au logiciel de jeu dans lequel des éléphants produisent des sons, des barrissements en l’occurrence. Pour l’illustrer, prenons le cas de l’opération barrir, qui est fortement couplée à l’utilisation d’une carte son, de fichiers audio codés dans des formats numériques nombreux et variés. Cette préoccupation est technique. Elle dérive d’une préoccupation plus amont : le besoin (dit « métier ») du jeu lui-même. Le jeu traite en effet d’animaux, d’éveil, de pédagogie, d’interactivité… pour divertir et éduquer. 1.2.1 Métier versus technologie Le programmeur doit gérer deux flux de complexité. Celui des exigences d’abord, complexes par essence, qui sont relatives aux fonctionnalités « métier » que doit offrir le jeu. Il y a ensuite la complexité technologique : connaître les formats numériques audio,savoir programmer des sons dans un logiciel… Ce phénomène de double flux est traité par le principe de séparation des préoccupations (separation of concerns en anglais). Selon ce principe, on ne s’intéresse dans un premier temps qu’aux propriétés métier1. Ces propriétés sont logiquement visibles de l’extérieur (on dit aussi « publiques », voir les littéraux public de Java et public: de C++ utilisés dans les autres chapitres de cet ouvrage). Les propriétés technologiques doivent, elles, être immergées2 de manière que tout programmeur (ré)utilisant la classe Éléphant puisse faire barrir ses objets logiciels éléphants sans avoir de connaissance spéciale sur les technologies à même de produire des sons dans un ordinateur. Il en résulte que les classes au départ uniquement dotées de propriétés métier (voir figure 1.3) s’étoffent avec des propriétés plus techniques (voir figure 1.5)3. À la figure 1.5, on préfixe le signe + aux propriétés métier pour dire qu’elles sont visi- bles et donc manipulables de l’extérieur alors que la nouvelle propriété source son de type uploads/Philosophie/7367-chap01.pdf

  • 25
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager