En programmation , une classe est une structure d'entité syntaxique utilisée pour créer des objets . Les capacités d'une classe diffèrent selon les langages de programmation , mais en général, les aspects communs consistent en un état ( variables ) et un comportement ( méthodes ) qui sont chacun associés soit à un objet particulier, soit à tous les objets de cette classe.
L'état d'un objet peut différer d'une instance de la classe à l'autre, tandis que l'état de la classe est partagé par toutes les instances. Les méthodes d'objet permettent d'accéder à l'état de l'objet (via un paramètre implicite ou explicite qui y fait référence), contrairement aux méthodes de classe.
Si le langage prend en charge l'héritage , une classe peut être définie à partir d'une autre classe, en conservant son état et son comportement, ainsi que des états et comportements supplémentaires qui la spécialisent davantage. La classe spécialisée est une sous-classe , et la classe dont elle est issue est sa superclasse .
Dans les langages de programmation purement orientés objet, tels que Java et C# , toutes les classes peuvent faire partie d'un arbre d'héritage tel que la classe racine est Object, ce qui signifie que toutes les instances d'objets sont de Objectou étendent implicitement Object, ce qui est appelé un type supérieur .
Histoire
Ce concept a été introduit principalement dans la programmation orientée objet par le langage Simula dans les années 1960 et est depuis lors utilisé de manière continue dans de nombreux langages de programmation. Sa création s'inspirait d'un concept similaire à celui des blocs utilisés dans le langage de programmation ALGOL 68 , basé sur les a priori .
Attributs
cycle de vie d'un objet
La plupart des langages permettent une logique personnalisée lors des événements du cycle de vie via un constructeur et un destructeur .
Taper
Un objet exprime un type de données sous forme d'interface unestructure de données concrète et un ensemble de sous-routines — qu'un type est une interface . Différentes classes (concrètes) peuvent produire des objets du même type ( abstrait ) (selon le système de types). Par exemple, le type (interface) Stack peut être implémenté par SmallStack , rapide pour les petites piles mais peu performant à grande échelle, et par ScalableStack , performant à grande échelle mais avec une surcharge importante pour les petites piles.
Structure

Une classe contient des champs de données décrits syntaxiquement (ou propriétés , champs , membres de données ou attributs ). Il s'agit généralement de types et de noms de champs qui seront associés à des variables d'état lors de l'exécution du programme ; ces variables d'état appartiennent soit à la classe, soit à des instances spécifiques de celle-ci. Dans la plupart des langages, la structure définie par la classe détermine l'organisation de la mémoire utilisée par ses instances. D'autres implémentations sont possibles : par exemple, en Python , les objets utilisent des conteneurs associatifs clé-valeur.
Certains langages de programmation, comme Eiffel, permettent de spécifier des invariants dès la définition de la classe et de les garantir par le biais du système de types. L'encapsulation de l'état est nécessaire pour pouvoir appliquer les invariants de la classe.
Comportement
classYclassYinterfaceXclassZinterfaceXDans les langages qui prennent en charge les spécificateurs d'accès , l'interface d'une classe est considérée comme l'ensemble des membres publics de la classe, y compris les méthodes et les attributs (via des méthodes getter et setter implicites ) ; les membres privés ou les structures de données internes ne sont pas destinés à être utilisés par le code externe et ne font donc pas partie de l'interface.
La méthodologie de programmation orientée objet exige que les opérations de toute interface d'une classe soient indépendantes les unes des autres. Il en résulte une architecture en couches où les clients d'une interface utilisent les méthodes déclarées dans cette interface. Une interface n'impose aucun ordre d'appel de ses opérations. Cette approche présente l'avantage que le code client peut supposer que les opérations d'une interface sont disponibles dès lors qu'il a accès à l'objet.
Exemple d'interface
Les boutons situés en façade de votre téléviseur constituent l'interface entre vous et le câblage électrique dissimulé derrière son boîtier en plastique. Vous appuyez sur le bouton « marche/arrêt » pour allumer ou éteindre le téléviseur. Dans cet exemple, votre téléviseur représente l'instance, chaque méthode est associée à un bouton, et l'ensemble des boutons forme l'interface (d'autres téléviseurs du même modèle que le vôtre possèdent la même interface). De manière générale, une interface est la spécification d'un groupe de méthodes apparentées, sans implémentation associée.
Un téléviseur possède une multitude d' attributs , comme sa taille et sa compatibilité avec la couleur, qui constituent sa structure. Une classe représente la description complète d'un téléviseur, incluant ses attributs (structure) et ses boutons (interface).
Le nombre total de téléviseurs fabriqués pourrait être implémenté par une méthode statique de la classe « téléviseur ». Cette méthode est associée à la classe, mais n'est pas accessible à chaque instance de celle-ci. Une méthode statique permettant de trouver une instance particulière parmi l'ensemble de tous les objets « téléviseur » en est un autre exemple.
Accessibilité des membres
Voici un ensemble courant de spécificateurs d'accès :
- L'attribut private (ou class-private ) restreint l'accès à la classe elle-même. Seules les méthodes appartenant à la même classe peuvent accéder aux membres privés.
- L'attribut protected (ou class-protected ) permet à la classe elle-même et à toutes ses sous-classes d'accéder au membre.
- Public signifie que n'importe quel code peut accéder au membre par son nom.
Bien que de nombreux langages orientés objet prennent en charge les spécificateurs d'accès ci-dessus, leur sémantique peut différer.
La conception orientée objet utilise les spécificateurs d'accès, associés à une conception rigoureuse des implémentations des méthodes publiques, afin de garantir les invariants de classe, c'est-à-dire les contraintes sur l'état des objets. Un usage courant des spécificateurs d'accès consiste à séparer les données internes d'une classe de son interface : la structure interne est rendue privée, tandis que les méthodes d'accès publiques permettent d'inspecter ou de modifier ces données privées.
Les spécificateurs d'accès ne contrôlent pas nécessairement la visibilité , car même les membres privés peuvent être visibles par le code externe du client. Dans certains langages, un membre inaccessible mais visible peut être référencé à l'exécution (par exemple, par un pointeur renvoyé par une fonction membre), mais toute tentative d'utilisation de ce membre par son nom depuis le code client sera bloquée par le vérificateur de types.
Les différents langages de programmation orientés objet imposent l'accessibilité et la visibilité des membres à des degrés divers, et selon leur système de types et leurs règles de compilation, cette imposition peut avoir lieu à la compilation ou à l'exécution . Par exemple, le langage Java interdit la compilation du code client accédant aux données privées d'une classe. En C++ , les méthodes privées sont visibles, mais inaccessibles dans l'interface ; toutefois, elles peuvent être rendues invisibles en déclarant explicitement des classes totalement abstraites représentant les interfaces de la classe.
Certaines langues proposent d'autres systèmes d'accessibilité :
- Accessibilité par instance vs. par classe : Ruby prend en charge les spécificateurs d’accès `instance-private` et `instance-protected` au lieu de `class-private` et `class-protected`, respectivement. Ils diffèrent en ce qu’ils restreignent l’accès en fonction de l’instance elle-même, plutôt que de la classe de l’instance.
- Ami : C++ prend en charge un mécanisme permettant à une fonction explicitement déclarée comme fonction amie de la classe d'accéder aux membres désignés comme privés ou protégés.
- Accès par chemin : Java permet de restreindre l’accès à un membre au sein d’un package Java , selon le chemin logique du fichier. Cependant, il est courant, lors de l’extension d’un framework Java, d’implémenter des classes dans le même package qu’une classe du framework pour accéder à des membres protégés. Le fichier source peut se trouver à un emplacement complètement différent et être déployé dans un fichier .jar distinct , tout en appartenant au même chemin logique du point de vue de la JVM.