Classe (informatique) - Définition

Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs est disponible ici.

En programmation orientée objet, une classe déclare des propriétés communes à un ensemble d'objets. La classe déclare des attributs représentant l'état des objets et des méthodes représentant leur comportement.

Une classe représente donc une catégorie d'objets. Il apparaît aussi comme un moule ou une usine à partir de laquelle il est possible de créer des objets. On parle alors d'un objet (De manière générale, le mot objet (du latin objectum, 1361) désigne une entité définie dans...) en tant qu'instance d'une classe (création d'un objet ayant les propriétés de la classe).

Il est possible de restreindre l'ensemble (En théorie des ensembles, un ensemble désigne intuitivement une collection...) d'objets représenté par une classe A grâce à un mécanisme d'héritage. Dans ce cas, on crée une nouvelle classe B liée à la classe A et qui ajoute de nouvelles propriétés. Dans ce cas, différents termes sont utilisés :

  • A est une généralisation de B et B est une spécialisation de A,
  • A est une super-classe de B et B est une sous-classe de A,
  • A est la classe mère de B et B est une classe fille de A.

Exemples de classe

Dans les exemples ci-dessous est définie dans différents langages une classe Point (Graphie) avec deux attributs x et y. Cette classe contient un constructeur, deux méthodes retournant la valeur des attributs (getX() et getY()), une méthode déterminant si le point représente l'origine (isOrigin()) et une méthode effectuant une translation.

  • En C++
 
 class (CLASS (CLS) est un célèbre groupe de l'underground informatique. CLASS a cessé son...) Point { 
 protected: 
 int x; 
 int y; 
 public: 
 Point(int x, int y) { 
 this->x = x; 
 this->y = y; 
 } 
 int getX() { return x; } 
 int getY() { return y; } 
 bool isOrigin() { return (x == 0) && (y == 0); } 
 Point& translate(Point point) { 
 Point* newPoint = new Point(x + point.x, y + point.y); 
 return *newPoint; 
 } 
 }; 
 
  • En Java
 
 public class Point { 
 // déclaration des attributs 
 int x; 
 int y; 
 // Constructeur: définit l'initialisation de la classe. 
 public Point(int x, int y) { 
 this.x = x; 
 this.y = y; 
 } 
 public int getX() { return x; } 
 public int getY() { return y; } 
 public boolean isOrigin() { return (x == 0) && (y == 0); } 
 public Point translate(Point point) { 
 return new Point(x + point.x, y + point.y); 
 } 
 } 
 
  • En Python
 
 class Point: 
 def __init__(self, x, y): 
 self.x = x 
 self.y = y 
 def getX(self): return self.x 
 def getY(self): return self.y 
 def isOrigin(self): 
 return (self.x == 0) and (self.y == 0) 
 def translate(self, point): 
 return Point(self.x + point.x, self.y + point.y) 
 

Cas particuliers de classe

Classe abstraite

Dans certains langages, une classe peut être partiellement définie. En particulier, certaines méthodes de cette classe n'ont pas de corps ou d'implémentation (Le mot implantation peut avoir plusieurs significations :). Ces méthodes sont dites abstraites (ou virtuelles en C++).

Les classes possédant au moins une méthode abstraite sont aussi dites classes abstraites (ou virtuelles) et ne peuvent pas être instanciées directement -sauf en créant une sous-classe non abstraite.

Exemple : On souhaite modéliser les relations objets d'un dessin vectoriel. On peut dire qu'un objet dessin est un ensemble de géométries (la classe abstraite) et chaque géométrie (La géométrie est la partie des mathématiques qui étudie les figures de l'espace...) peut être un point, un polygone (En géométrie euclidienne, un polygone (du grec polus, nombreux, et gônia, angle) est...) ou une ligne brisée (ces trois classes héritent de géométrie). La classe abstraite n'est donc pas indispensable en soi, mais elle est indispensable[1] pour un modèle propre, générique et simplifié.

Le mixin (Un mixin, aussi appelé sous-classe abstraite, est une classe abstraite. C'est un cas de...) est un cas particulier de classe abstraite. Il permet d'ajouter un service aux sous-classes.

Interface (Une interface est une zone, réelle ou virtuelle qui sépare deux éléments. L’interface...)

Une classe ne possédant que des méthodes abstraites est appelée interface ou classe purement virtuelle (en C++) ou protocole (en Objective C).

Métaclasse (Une métaclasse est une classe dont les instances sont des classes. Autrement dit, une métaclasse...)

La classe d'une classe est une métaclasse. Les métaclasses permettent de réaliser de la réflexion structurelle.

Manipulation des données membres

Accès aux membres d'une classe

Une classe, comme définie précédemment, est un ensemble de membres typés (méthodes et attributs) qu'on est forcément amené à manipuler. Si p est une instance de Point(a,b)a et b sont de type int, on accède aux membres de p comme ceci :

  • p.x = a et p.y = b (accès aux attributs)
  • p.getX() et p.getY() (accès aux méthodes)

La question qui vient tout (Le tout compris comme ensemble de ce qui existe est souvent interprété comme le monde ou...) de suite à l'esprit est la suivante : pourquoi définir une méthode getX(), alors qu'on peut accéder directement aux champs x et y de la classe Point ?

En fait, lorsqu'on est amené à manipuler de nombreuses classes ainsi que de nombreuses relations entre ces classes (cf. héritage), le schéma, les données et les opérations peuvent devenir très complexes (surtout pour un individu (Le Wiktionnaire est un projet de dictionnaire libre et gratuit similaire à Wikipédia (tous deux...) n'ayant pas conçu le code). On a donc recours à un mécanisme qu'on appelle encapsulation (L'encapsulation en général est la notion de mettre une chose dans une autre. En imageant, on peut...) des données, lequel se charge (La charge utile (payload en anglais ; la charge payante) représente ce qui est effectivement...) de masquer à certaines parties du programme les champs de la classe dans un souci d'intégrité. L'utilisateur est donc amené à ne manipuler que des méthodes qui ont été approuvées et qui en théorie (Le mot théorie vient du mot grec theorein, qui signifie « contempler, observer,...) remplissent bien leur rôle.

Selon le principe d'encapsulation, les méthodes ont un accès public - cela signifie que tout élément d'un programme peut utiliser une méthode. Quant aux attributs composant l'état, ils ont un accès privé (private) - seul l'objet lui-même (et donc les méthodes qu'il contient) a un accès direct (Un logiciel fait un accès direct (aussi appelé accès aléatoire) à un...) à ses attributs. Dans ce cas, le seul moyen d'accéder à ces attributs est d'utiliser les méthodes de l'objet. Les attributs ne peuvent pas être utilisés directement par un autre élément du programme ni même un autre objet, même si cet objet est de la même classe. Autre point : tous les attributs d'un objet qui sont hérités sont directement accessibles par les autres membres de cet objet.

En ce qui concerne les dernières remarques, il y a souvent confusion sur la sémantique de l'accès privé. Le principe d'encapsulation implique une protection des attributs que nous appellerons verticale (seuls l'objet lui-même et les objets d'une sous-classe y ont accès). Nous retrouvons cette sémantique dans des langages comme Smalltalk (Smalltalk est un langage de programmation orienté objet, réflexif et dynamiquement...), Oz ou OCaml. Cependant certains langages, comme C++ ou Java, plaident pour une protection des attributs que nous appellerons horizontale (les objets d'une même classe y ont accès, mais pas les objets des sous-classes).

Contrôle (Le mot contrôle peut avoir plusieurs sens. Il peut être employé comme synonyme d'examen, de...) de l'accès aux membres d'une classe et visibilité (En météorologie, la visibilité est la distance à laquelle il est possible de...)

Certains langages proposent de changer le type d'accès des membres d'un objet. Cette opération s'effectue au sein des classes de ces objets. Par exemple, le C++ propose les visibilités suivantes :

  • public : les membres peuvent être utilisés dans/et par n'importe quelle partie du programme (les méthodes définies de cette manière sont visibles et utilisables par l'utilisateur).
  • privé (private) : les membres privés d'une classe ne sont accessibles que par les objets de cette classe exactement et non par ceux d'une classe fille ou d'une autre classe.
  • protégé (protected) : comme les membres privés, mais ils peuvent être utilisés par les classes filles.

La sémantique de ces visibilités et leur nombre (La notion de nombre en linguistique est traitée à l’article « Nombre...) varient selon le langage. Par exemple, Java propose une définition (Une définition est un discours qui dit ce qu'est une chose ou ce que signifie un nom. D'où la...) un peu différente (En mathématiques, la différente est définie en théorie algébrique des...) pour les membres protégés (elle s'étend à l'ensemble des objets de la même classe, des classes filles et des classes du même paquetage). Python propose aussi la possibilité de modifier la visibilité des membres d'une classe en préfixant le nom du membre par le caractère souligné ('_'). Par exemple, getX() est une méthode public, _getX() est seulement utilisable par les éléments du même module et __getX() est privé.

Surcharge d'opérateur (Le mot opérateur est employé dans les domaines :)

voir également: Surcharge des opérateurs

Lorsqu'on est amené à manipuler des données de même type (c'est par exemple le cas de points dans un repère), on peut vouloir appliquer à ces objets (au sens (SENS (Strategies for Engineered Negligible Senescence) est un projet scientifique qui a pour but...) de la POO) des opérations. Ainsi, la fusion (En physique et en métallurgie, la fusion est le passage d'un corps de l'état solide vers l'état...) de deux zones (polygones) donne bien une nouvelle zone, tout comme l'addition (L'addition est une opération élémentaire, permettant notamment de décrire la...) de deux points donne un nouveau point.

  • Pour une addition de points, une première méthode consisterait à créer une méthode membre de la classe Point qu'on nommerait translate(Point) et qui renverrait un nouveau Point ayant subi l'addition. On a :
 
 ... 
 p=Point(6,2) 
 q=Point(6,3) 
 m=Point(0,0) 
 m=p.translate(q) // p+q 
 ... 
 
  • En fait une notation plus naturelle et beaucoup plus simpliste serait de représenter l'addition tout simplement par m = p+q. Pour cela on utilise un mécanisme appelé surcharge d'opérateurs, qui redéfinit un opérateur donné pour une action donnée (Dans les technologies de l'information (TI), une donnée est une description élémentaire, souvent...)[2].

Continuons sur notre classe Point. L'exemple Python suivant est très parlant :

 
 class Point: 
 (...) 
 def __add__(self,point):                             # Surcharge de '+' 
 return Point(self.x + point.x, self.y + point.y) 
 p=Point(0,0) 
 q=Point(2,3) 
 r=p+q 
 

Ainsi r.getX() retournera 2.

Notes et références

  1. On aurait très bien pu dire qu'un dessin vectoriel est un ensemble de polygones, de lignes et de points. Mais on s'aperçoit que, si on veut ajouter une géométrie plus complexe, il faut modifier la structure même de la classe mère, ce qui est ridicule.
  2. On peut bien évidemment surcharger l'opérateur '+' pour qu'il réalise autre chose que l'addition de Points. Cependant une multiplication (La multiplication est l'une des quatre opérations de l'arithmétique élémentaire...) de surcharges mal choisies contribuerait à alourdir le code et à le rendre illisible.
Cet article vous a plu ? Partagez-le sur les réseaux sociaux avec vos amis !
Page générée en 0.035 seconde(s) - site hébergé chez Contabo
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
A propos - Informations légales | Partenaire: HD-Numérique