# Classe (informatique)

En programmation orientée objet, la déclaration d'une classe regroupe des membres, méthodes et propriétés (attributs) communs à un ensemble d'objets.
La classe déclare, d'une part, des attributs représentant l'état des objets et, d'autre part, des méthodes représentant leur comportement.
Une classe représente donc une catégorie d'objets. Elle apparaît aussi comme un moule ou une usine à partir de laquelle il est possible de créer des objets ; c'est en quelque sorte une « boîte à outils » qui permet de fabriquer un objet. On parle alors d'un objet 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 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 :

## Exemple de classe dans différents langages

Dans les exemples ci-dessous on définit dans différents langages une classe Point 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)
* une méthode effectuant une translation.
Le constructeur est une règle de procédures d’initialisation qui sera appelée lors de la création d'une nouvelle instance d'une classe. Il définit un premier état valide pour l'état interne de l’objet. Cette règle peut se traduire sommairement par la notion de « déclaration de structures, de variables ». Il peut y avoir plusieurs constructeurs déclarés. En l’absence de constructeur, le compilateur en génèrera un par défaut.
La méthode est une règle de procédures appliquée aux attributs de la classe. Cette règle peut se traduire sommairement par la notion de « fonction » ou « routine ». Il peut y avoir plusieurs méthodes dans une classe. Les méthodes sont les éléments clés de la classe.

### Javascript

À partir de l’édition de 2015 (ECMAScript 6), une syntaxe de définition de classes a été ajoutée, simplifiant l’utilisation de son mécanisme d’héritage prototypal pour le développement orienté objet :

### Swift 3 et 4
## Cas particuliers de classe
### Classe immuable

Une classe est dite immuable s'il n'est pas possible de modifier un objet de cette classe après sa création. Par exemple, la classe Point, décrite ci-dessus dans différents langages, est immuable car elle n'expose aucune méthode permettant de modifier la valeur de ses variables membres. La méthode translate retourne un nouvel objet au lieu de modifier l'objet lui-même. La classe java.lang.String de l'environnement Java est un autre exemple de classe immuable, tout comme la classe System.String du Framework Microsoft .NET.

### 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. 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 peut être un point, un polygone 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 pour un modèle propre, générique et simplifié.
Le mixin est un cas particulier de classe abstraite. Il permet d'ajouter un service aux sous-classes.

### 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

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 (méthodes et attributs) qu'on est forcément amené à manipuler. Si p est une instance de Point(a,b) où 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 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 n'ayant pas conçu le code). On a donc recours à un mécanisme qu'on appelle encapsulation des données, lequel se charge 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 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 à 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, Oz ou OCaml. Cependant certains langages, comme C++, Pascal 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 de l'accès aux membres d'une classe et visibilité

Certains langages permettent, lors de la déclaration de la classe, de modifier la portée de ses membres et, par conséquent, des membres des objets instanciés à partir de cette classe; la modification de la portée réduit la visibilité et, par conséquent, l'accessibilité aux membres.
Par exemple, les langages C++ et Pascal Objet proposent les modifications de portée suivantes :
Portées (visibilités) des membres d'une classe :
| Portée | Mot clé | Visible (accessible) par | Visible (accessible) par | Visible (accessible) par | Note |
| (visibilité) | en C++ | un membre de la classe | une classe dérivée | un client de l'objet | Note |
| public | public | oui | oui | oui | Les membres publics sont aussi accessibles que l'objet instancié de cette classe (les membres déclarés dans cette portée sont visibles et utilisables par le client de l'objet). |
| protégé | protected | oui | oui | non | Les membres protégés ne sont accessibles que par les membres de l'objet instancié de cette classe et par les classes qui en sont dérivées. |
| privé | private | oui | non | non | Les membres privés ne sont accessibles que par les membres de l'objet instancié de cette classe (ils ne sont pas accessibles par une classe fille ou le client de l'objet). |
La sémantique de ces modifications de portée et leur nombre varient selon le langage de programmation.
Par exemple, Java propose une définition un peu différente 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.
Par exemple, Python propose la possibilité de modifier la visibilité des membres d'une classe en préfixant le nom du membre par le caractère souligné ('_'):
* getX est une méthode publique.
* _getX est une méthode protégée, c'est-à-dire accessible seulement par les éléments du même module.
* __getX est une méthode privée.

## Surcharge d'opérateur

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 de la POO) des opérations. Ainsi, la fusion de deux zones (polygones) donne bien une nouvelle zone, tout comme l'addition 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 :
* 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.
Continuons sur notre classe Point. L'exemple Python suivant est très parlant :
Ainsi r.getX retournera 2.