Classes et objets
En programmation orientée objet comme Pascal Objet, Java ou C++, nous devons créer des classes qui seront par la suite utilisées pour créer des objets que nous pourrons manipuler en appelant leurs méthodes. Mais la littérature n'est pas toujours très claire pour nous aider à bien comprendre les concepts de classe et d'objet. En effet, ce sont deux concepts que l'on confond souvent, malgré le fait qu'il s'agisse de deux choses bien différentes.
Une classe a deux fonctions principales :
- elle sert de plan pour créer des objets
- elle désigne une frontière: il y a des choses qui sont dans la classe et d'autres qui sont en-dehors.
Une classe contient des données et des méthodes. Mais toutes les données et les méthodes ne font pas nécessairement partie du plan pour construire les objets. En effet, les données et les méthodes déclarées static ne font pas partie du plan et ne seront donc pas placées dans un objet lorsqu'il sera créé.
Par contre, les données et les méthodes qui ne sont pas static font partie du plan et se retrouveront dans chaque objet qui sera créé à l'aide de ce plan. Mais si aucun objet n'est créé, ces données et ces méthodes n'existent pas. C'est comme un plan de maison : on a beau connaître la disposition des pièces, on ne pourra pas les utiliser seulement à partir du plan. Il faudra d'abord construire la maison pour y accéder.
Alors tant les éléments static que ceux qui ne le sont pas, sont à l'intérieur de la frontière de la classe, mais ceux qui ne sont pas déclarés static ne sont qu'un plan.
On considère la classe comme un type et un objet donné comme une variable de ce type. De la même façon que x peut être de type float, y peut être de type Figure. On dira alors que x est une instance du type float et que y est une instance de la classe Figure.
De façon générale, float et Figure sont des modèles, alors que x et y sont des espaces mémoire conformes à ces modèles. Dit autrement, on pourrait dire que float et Figure ne se retrouvent pas en mémoire de l'ordinateur et qu'à l'inverse, x et y n'existent que dans la mémoire de l'ordinateur. Mais si c'est vrai pour float, ce ne l'est pas tout à fait pour Figure.
En effet, on ne peut pas utiliser un float si on n'a pas une variable de ce type. De la même façon, on ne peut pas utiliser un objet de type Figure si on n'a pas d'objet de ce type. Pour avoir un objet de type Figure, on va en créer un avec l'opérateur new. Cet opérateur va créer un espace mémoire pour y placer les variables et méthodes de la classe.
C'est ce qu'on appelle instancier une classe. Pour ma part, cette expression m'apparaît un peu abusive parce qu'elle laisse entendre qu'on obtiendra une copie physique (en mémoire) de la classe décrite dans le code, alors que ce sont seulement les méthodes et variables qui ne sont pas déclarées static qui se retrouveront dans l'objet. Celles déclarées static n'y seront pas. Il n'est donc pas possible d'instancier une classe qui n'a que des variables et méthodes static.
Ce n'est donc pas toute la classe qui est utilisée comme modèle pour créer des objets, mais seulement une partie. En complément, l'autre partie de la classe (déclarée static) n'entre pas dans la composition des objets, mais existe déjà en mémoire.
On verra donc le plus souvent dans la littérature qu'un objet est une instance d'une classe, et que ses variables et méthodes sont des variables d'instance et des méthodes d'instance. Celles déclarées static, qui ne font donc pas partie des objets, sont des variables de classe et méthodes de classe.
Pour ma part, je préfère dire que l'on crée un objet à partir d'une classe, puis que cet objet a ses propres variables et méthodes.
Par ailleurs, si on peut créer plusieurs objets différents à partir d'une classe, chacun avec ses propres variables et méthodes, la partie static n'existe en mémoire qu'en un seul exemplaire. Cependant, cette partie existe déjà au lancement du programme et on n'a donc pas à la créer. Il est alors possible d'appeler une méthode de classe sans devoir d'abord créer un objet. À l'opposé, on ne peut appeler une méthode d'objet qu'à partir d'un objet que l'on a préalablement créé, puisque cette méthode n'existe que dans l'objet ; dans la classe, elle n'est qu'un plan.
Dans les faits, côté pratique, comme les méthodes ne changent pas (contrairement au contenu des variables) le système ne conserve qu'une copie d'une méthode d'objet qui est partagée par tous les objets du même type (en plaçant dans l'objet, un pointeur vers cette méthode). Cependant, ce n'est qu'une question d'implémentation physique. Conceptuellement, c'est plus juste d'imaginer que les variables et méthodes d'objets se trouvent effectivement à l'intérieur des objets.
La figure suivante montre ces principes d'une façon schématique.