Premiers principes de la programmation objet

Cette conférence présente les premiers principes de la programmation orientée objet, un paradigme fondamental en génie logiciel. Elle s’inscrit dans un cours plus large sur la conception et le développement logiciel, et introduit les concepts clés tels que les objets, les classes, l’héritage, les interfaces, le polymorphisme, ainsi que les notions de visibilité et d’association.

D'après le document Premiers principes de la programmation objet

Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Premiers principes de la programmation objet

Document source

Premiers principes de la programmation objet

Software Engineering · PDF · 34 pages · 2015

Afficher l'aperçu du document

Consulter le document original →

Cette conférence présente les premiers principes de la programmation orientée objet, un paradigme fondamental en génie logiciel. Elle s’inscrit dans un cours plus large sur la conception et le développement logiciel, et introduit les concepts clés tels que les objets, les classes, l’héritage, les interfaces, le polymorphisme, ainsi que les notions de visibilité et d’association.

Concepts fondamentaux de la programmation orientée objet

Un objet est défini par trois caractéristiques principales :

  • Ses propriétés, appelées attributs, qui représentent son état.
  • Ses opérations, ou méthodes, qui définissent les comportements de l’objet.
  • Son identité, qui correspond à son adresse mémoire unique.

Une classe définit un type d’objets. Elle regroupe un ensemble d’objets partageant des propriétés et des méthodes communes. Une classe est donc une intension, tandis que ses instances sont les objets concrets. Chaque objet est une instance de sa classe.

Avantages de la programmation orientée objet

La programmation orientée objet offre plusieurs bénéfices :

  • La pérennité des objets, indépendamment des fonctionnalités spécifiques.
  • La modularité, facilitant la structuration du code.
  • La réutilisabilité des composants logiciels.
  • Une meilleure structuration des données manipulées.
  • L’encapsulation, qui protège l’état interne des objets.
  • L’abstraction et la possibilité de traitements génériques.
  • Une facilité accrue pour les tests logiciels.

Classes, héritage et polymorphisme

Une classe peut être centrée sur ses attributs, avec des méthodes d’accès (accesseurs) et de modification (mutateurs). Par exemple, une classe peut avoir des méthodes getName, getPrice pour accéder aux attributs, et setPrice pour modifier un prix, tandis que certains attributs comme available peuvent être encapsulés et non accessibles directement.

L’héritage permet à une classe fille (F) de dériver d’une classe mère (M) :

  • La classe fille hérite de tous les attributs et méthodes de la classe mère.
  • Elle peut ajouter des attributs et méthodes supplémentaires.
  • Elle peut redéfinir certaines méthodes héritées (surcharge).
  • Les instances de la classe fille peuvent être traitées comme des instances de la classe mère, ce qui est la base du polymorphisme.

En Java, cela s’exprime par la syntaxe class F extends M.

Classes abstraites et interfaces

Une méthode abstraite est une méthode déclarée mais non définie dans une classe. Une classe abstraite est une classe qui ne peut pas être instanciée directement. Elle peut contenir des méthodes abstraites, ce qui impose aux sous-classes de les définir, mais elle peut aussi contenir des méthodes entièrement définies.

Une interface est un ensemble de déclarations de méthodes sans attributs (sauf des constantes final static). Une classe qui implémente une interface doit définir toutes ses méthodes. En Java, une classe peut implémenter plusieurs interfaces avec la syntaxe class C implements I1, I2, I3.

Les interfaces servent principalement à définir un type caractérisé par des traitements applicables ou des opérations disponibles.

Exemples d’application : tri et médiathèque

Un exemple de classe utilisant le polymorphisme est une classe de tri, telle que Quicksort, qui manipule des listes d’objets implémentant une interface Ordered. La méthode getOrderedList() compare les éléments avec une méthode isGreaterThan pour ordonner la liste.

Une architecture classique de médiathèque peut être modélisée avec des classes et des interfaces, illustrant la modularité et la réutilisabilité des composants.

Délégation et distinction entre méthodes d’instance et méthodes de classe

La délégation est une technique où une classe utilise une autre classe pour réaliser une fonctionnalité, plutôt que d’hériter de celle-ci.

Il est important de distinguer les méthodes d’instance des méthodes de classe :

  • Les méthodes d’instance dépendent de l’état courant de l’objet et sont appelées sur une instance. Par exemple, les accesseurs et mutateurs.
  • Les méthodes de classe, en Java déclarées avec le mot-clé static, ne dépendent que de la classe et sont appelées directement sur celle-ci. Par exemple, la méthode main ou Integer.parseInt("0347").

Les attributs peuvent également être de classe ou d’instance.

Polymorphisme et liage dynamique

Le polymorphisme permet de manipuler des objets de différentes classes dérivées à travers une référence de type parent. Par exemple, une liste d’objets de type Appartment peut contenir des instances de Appartment ou de sous-classes comme AgencyAppartment. L’appel d’une méthode telle que getRent() sur une référence parent exécutera la version de la méthode correspondant au type réel de l’objet.

Le liage dynamique signifie que le code à exécuter pour une méthode n’est pas toujours connu à la compilation. Il est déterminé à l’exécution en fonction du type réel de l’objet, ce qui permet la redéfinition des méthodes dans les sous-classes.

Par exemple, un tableau de véhicules peut contenir des voitures et des vélos, et l’appel de la méthode tourner() sur chaque élément exécutera la version spécifique à la classe réelle de l’objet.

Références versus instances

  • Une instance n’a pas de nom propre, mais peut être référencée par plusieurs références.
  • Une référence peut pointer vers un objet de son type ou d’un sous-type grâce au polymorphisme, y compris vers des types abstraits.
  • Une instance est toujours concrète (non abstraite) et possède toutes ses méthodes définies.
  • Le liage dynamique garantit que la méthode exécutée est celle correspondant à la définition la plus spécifique dans la hiérarchie de classes, en fonction du type réel de l’objet.

Héritage ou association ?

Il est important de ne pas confondre héritage et association. L’héritage est justifié lorsque le polymorphisme a un sens sémantique, c’est-à-dire si une instance de la classe fille est bien un élément de la classe mère. Par exemple, un cabriolet est une voiture, qui est un véhicule.

En revanche, un cercle n’est pas un point, mais possède un centre qui est un point. Cette relation est une association, pas un héritage.

Un exemple de délégation est donné avec la classe Cercle qui délègue la méthode translate(dx, dy) à son attribut centre de type Point.

La modélisation par héritage peut devenir problématique lorsque les combinaisons d’attributs ou fonctionnalités sont nombreuses, comme pour des pizzas avec différents ingrédients. La multiplication des sous-classes mène à une explosion du nombre de classes et à de la redondance, ce qui invite à utiliser des design patterns adaptés.

Visibilité des attributs et méthodes

La visibilité contrôle l’accès aux attributs et méthodes :

  • public : accessible partout.
  • private : accessible uniquement dans la classe elle-même, y compris dans d’autres instances de la même classe.
  • protected : accessible dans la classe et ses sous-classes.
  • package (Java) : accessible dans le même package.

La surcharge de méthode peut augmenter la visibilité, mais il est impossible de la restreindre.

Notation UML et diagrammes

La notation UML est utilisée pour représenter les classes, leurs attributs, méthodes, relations d’héritage, d’association, et interfaces. Cependant, il est conseillé d’utiliser les diagrammes de manière parcimonieuse :

  • Les diagrammes doivent simplifier la communication.
  • Un diagramme complet est souvent redondant avec le code source et donc inutile.
  • Il faut ne montrer que ce qui est pertinent dans le contexte.
  • Il est important de distinguer les points de vue : présentation, implémentation, utilisation.
  • Les attributs et méthodes privés doivent être cachés sauf pour l’implémentation.

Points clés

  • Un objet est défini par ses attributs, méthodes et identité.
  • Une classe regroupe des objets partageant des propriétés et comportements communs.
  • L’héritage permet de créer des relations de type « est un » entre classes, favorisant le polymorphisme.
  • Les classes abstraites ne peuvent pas être instanciées et peuvent contenir des méthodes abstraites.
  • Les interfaces définissent des contrats de méthodes à implémenter, sans attributs.
  • Le polymorphisme et le liage dynamique permettent d’exécuter la méthode appropriée selon le type réel de l’objet.
  • La distinction entre héritage et association est essentielle pour une bonne modélisation.
  • La visibilité contrôle l’accès aux membres d’une classe et doit être gérée avec soin.
  • Les diagrammes UML doivent être utilisés de façon ciblée pour faciliter la communication sans redondance.

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions