La programmation orientée objet (POO) ou programmation par objet, est un paradigme de programmation informatique qui consiste en la définition et l’assemblage de briques logicielles appelées objets.

L’objet

Comme l’indique son nom, la composante principale de la Programmation Orientée Objet est l’objet. Un objet regroupe les données et les moyens de traitement de ces données.

Un objet rassemble de fait deux éléments :

  • Les attributs : ce sont les variables de l’objet : ce sont eux qui ont en charge les données à gérer. Dans la plupart des langages un attribut possède un type quelconque défini au préalable : nombre, caractère, ..., ou même un type objet.
  • Les méthodes : les méthodes sont les éléments d’un objet qui servent d’interface entre les données et le programme. Ce sont en fait les procédures ou fonctions destinées à traiter les données.


Objet et classe

L’autre notion importante qui est inséparable de l’Objet, c’est la notion de classe. L’objet est une instance de classe, plus simplement un exemplaire d’une classe, sa représentation en mémoire. Par conséquent, on déclare comme type une classe, et on déclare des variables de ce type appelées des objets.

Exemple de classe en Java :

public class MaClasse {
....
}


Exemple d’objet (et donc d’instanciation) en Java :

MaClasse monObject = new MaClasse();

 

Les 3 fondamentaux de la POO

La Programmation Orientée Objet est dirigée par 3 fondamentaux : encapsulation, héritage et polymorphisme.


Encapsulation

L’encapsulation permet de faire voir l’objet à l’extérieur comme une boîte noire ayant certaines propriétés (attributs et fonctions) et ayant un comportement spécifié. La manière dont ces propriétés ont été implémentées est alors cachée aux utilisateurs de la classe. L’implémentation peut être modifiée sans changer le comportement extérieur de l’objet. Cela permet donc de séparer la spécification du comportement d’un objet, de l’implémentation pratique de ces spécifications.


Héritage

L’héritage, permettant entre autres la réutilisabilité et l’adaptabilité des objets. Ce principe est basé sur des classes dont les "filles" héritent des caractéristiques de leur(s) "mère(s)". Chacune des classes filles peut donc posséder les mêmes caractéristiques que ses classes mères et bénéficier de caractéristiques supplémentaires à celles de ces classes mères. Bien sur, toutes les méthodes de la classe héritée (fille) peuvent être redéfinies. Chaque classe fille peut, si le programmeur n’a pas défini de limitation, devenir à son tour classe mère.


Polymorphisme

Cette capacité dérive directement du principe d’héritage vu précédemment. En effet, comme on le sait déjà, un objet va hériter des attributs et méthodes de ses ancêtres. Mais un objet garde toujours la capacité de pouvoir redéfinir une méthode. On voit donc apparaître ici ce concept de polymorphisme : choisir en fonction des besoins quelle méthode ancêtre appeler, et ce au cours même de l’exécution.


Visibilité

De par le principe de l’encapsulation, il convient de pouvoir masquer certaines données et méthodes internes les gérant, et de pouvoir laisser visibles certaines autres devant servir à la gestion publique de l’objet. C’est le principe de la visibilité.


Attributs et méthodes publics

Les attributs et méthodes dits publics sont accessibles par tous.


Attributs et méthodes privés

La visibilité privée restreint la portée d’un attribut ou d’une méthode à l’objet où il ou elle est déclaré(e).


Attributs et méthodes protégés

La visibilité protégée correspond à la visibilité privée excepté que tout attribut ou méthode protégé(e) est accessible dans tous les descendants (c’est à dire dans toutes les classes filles).


Différents types de méthodes

Voici la description de quelques méthodes particulières à la Programmation Orientée Objet.


Constructeurs et destructeurs

Parmi les différentes méthodes d’un objet se distinguent deux types de méthodes bien particulières et remplissant un rôle précis dans sa gestion : les constructeurs et les destructeurs.


Constructeurs

Comme leur nom l’indique, les constructeurs servent à construire l’objet en mémoire. Un constructeur va se charger de mettre en place les données, d’associer les méthodes avec les attributs et de créer le diagramme d’héritage de l’objet, autrement dit de mettre en place toutes les liaisons entre les ancêtres et les descendants. Il peut exister en mémoire plusieurs instances d’un même type objet, par contre seule une copie des méthodes est conservée en mémoire, de sorte que chaque instance se réfère à la même zone mémoire en ce qui concerne les méthodes. Bien entendu, les attributs sont distincts d’un objet à un autre.

Quelques remarques concernant les constructeurs.

  • Un objet peut ne pas avoir de constructeur explicite, il est alors créer par le compilateur.
  • Certains langages (comme le Java) autorise d’avoir plusieurs constructeurs : c’est l’utilisateur qui décidera du constructeur à appeler. Comme pour toute méthode, un constructeur peut être surchargé, et donc effectuer diverses actions en plus de la construction même de l’objet. On utilise ainsi généralement les constructeurs pour initialiser les attributs de l’objet.
  • S’il n’est pas nécessaire de fournir un constructeur pour un objet statique, il devient obligatoire en cas de gestion dynamique, car le diagramme d’héritage ne peut être construit de manière correcte que lors de l’exécution, et non lors de la compilation.


Destructeurs

Le destructeur est le pendant du constructeur : il se charge de détruire l’instance de l’objet. La mémoire allouée pour le diagramme d’héritage est libérée. Certains compilateurs peuvent également se servir des destructeurs pour éliminer de la mémoire le code correspondant aux méthodes d’un type d’objet si plus aucune instance de cet objet ne réside en mémoire.

Quelques remarques sur les destructeurs :

  • Tout comme pour les constructeurs, un objet peut ne pas avoir de destructeur. Une fois encore, c’est le compilateur qui se chargera de la destruction statique de l’objet.
  • Certains langages autorise d’avoir plusieurs destructeurs. Leur rôle commun reste identique, mais peut s’y ajouter la destruction de certaines variables internes pouvant différer d’un destructeur à l’autre. La plupart du temps, à un constructeur distinct est associé un destructeur distinct.
  • En cas d’utilisation dynamique, un destructeur s’impose pour détruire le diagramme créé par le constructeur.


Méthodes et classes abstraites

Méthodes abstraites

Une méthode abstraite est une méthode qu’il est nécessaire de surcharger. Elle ne possède pas d’implémentation. Ainsi, si on tente d’appeler une méthode abstraite, une erreur est déclenchée. Les méthodes abstraites sont généralement utilisées lorsque l’on bâtit un squelette d’objet devant donner lieu à de multiples descendants devant tous posséder un comportement analogue.


Classe abstraite

On retrouve le même principe au niveau de la classe. Une classe abstraite ne peut pas être instanciée. Par contre il est possible d’y mélanger des méthodes abstraites et concrète.


Interface

Une interface est un cas particulier de la classe abstraite car toutes ces méthodes sont abstraites. Seule l’interface de la classe apparaît.


Méthode et attribut statique

Les méthodes et attributs statiques sont dits de classe. Un attribut statique existe dès que sa classe est chargée, en dehors et indépendamment de toute instanciation. Quelque soit le nombre d’instanciation de la classe, un attribut de classe, existe en un et un seul exemplaire.

Une méthode statique ne doit pas manipuler, directement ou indirectement, d’attributs non statiques de sa classe.


Pointeur interne

Il peut se révéler indispensable pour un objet de pouvoir se référencer lui-même. Pour cela, toute instance dispose d’un pointeur interne vers elle-même. Ce pointeur peut prendre différentes appellations. En Java, c++, PHP il s’agira du pointeur "this".

Commentaires
Ajouter un commentaire