Le concept d'objet
La programmation orientée objet (POO) repose sur l'idée d'objet. Un objet est une représentation informatique d'un objet de la vie réelle. Ça peut être une auto, un téléviseur, un livre, etc. Ça peut aussi être une partie d'un objet plus gros. Par exemple, une auto peut être composée d'autres objets comme le moteur, le volant, les roues, etc.
Diviser un programme en objets permet de gérer la complexité. Par exemple, je peux avoir un objet qui est une figure géométrique qui pourra être dessinée à l'écran ou sur l'imprimante. Mais plutôt que de simplement conserver une structure des données de la figure (position, grandeur, forme, etc.) et d'éventuellement me servir de ces données pour dessiner la figure à l'écran et plus tard sur l'imprimante, je vais m'organiser pour que la figure se dessine elle-même. De cette façon, si elle se dessine mal, je n'ai qu'un endroit à aller voir : à l'intérieur de l'objet.
Un objet contient donc deux choses :
- Des données qui le définissent. Ce sont ses attributs (position, largeur, hauteur, couleur, etc.).
- Des méthodes qui le font agir. Ce sont des procédures ou fonctions qui permettent de manipuler l'objet.
Alors plutôt que de regarder dans l'objet et utiliser ses attributs pour le dessiner, je lui demanderai simplement de se dessiner. Par exemple comme ceci :
figure.dessine(ecran);
ou encore :
figure.dessine(imprimante);
La méthode dessine() est en réalité une fonction (ou procédure) qui fait partie de l'objet au même titre que ses attributs. Le langage Pascal fait la différence entre une procédure et une fonction : les deux sont un ensemble d'instructions, mais la fonction retourne une valeur alors que la procédure ne retourne rien. Le langage C++ (duquel Java s'est inspiré) ne fait pas cette différence : ce sont toutes des fonctions, et celles qui ne retournent rien sont indiquées comme retournant void. Java utilise la même approche que le C++, mais parle le plus souvent de méthodes plutôt que de fonctions.
Une autre notion importante est que, comme programmeur, on se trouve tantôt à l'intérieur d'un objet, tantôt à l'extérieur de cet objet. Pour prendre un exemple de la vie courante, tantôt je regarde la télé, je suis donc à l'extérieur de cette télé, tantôt je la fais réparer, le réparateur travaille alors sur ses circuits: il est à l'intérieur de la télé. Le conducteur d'une auto est à l'extérieur de l'objet auto (même s'il est dans l'habitacle), alors que le mécanicien est à l'intérieur.
Comme programmeur, il m'arrive de fabriquer des objets. À ce moment je suis donc à l'intérieur de l'objet et j'ai accès à tout ce qui s'y trouve. Mais je peux aussi utiliser des objets, alors je suis à ce moment à l'extérieur et je suis limité quant aux choses auxquelles j'ai accès. Normalement, j'aurai seulement accès aux méthodes publiques de l'objet.
Pour revenir au téléviseur, le fabricant met quelques contrôles à notre disposition (volume, luminosité, contraste, canal, etc.). Ce sont les méthodes publiques. Mais à l'intérieur du téléviseur il y a d'autres contrôles qui ne nous sont pas accessibles et d'autres composantes qu'on ne connaît même pas. Le fabricant place un couvercle par-dessus tout ça pour nous en interdire l'accès. En POO, c'est l'encapsulation des données.
En effet, ma figure me permettra de la positionner ou de la changer de couleur en utilisant des méthodes, mais je n'ai pas à savoir ce qu'il y a à l'intérieur, ni comment elle s'y prend. Par exemple je peux faire :
figure.position(100, 200); figure.couleur(rouge);
Peu importe la façon dont la figure conserve ses attributs ou qu'elle arrive à faire ce qu'on lui demande, en autant que ça fonctionne. C'est comme le téléviseur : peu importe les détails des circuits, en autant que l'image soit belle. Ça laisse de la latitude au constructeur du téléviseur comme au programmeur. En effet, si je décide d'utiliser des nombres à virgule flottante plutôt que des entiers pour conserver la position de la figure, j'aurai simplement à modifier quelques détails à l'intérieur de l'objet, et tant que je ne modifierai pas la déclaration des méthodes, je n'aurai aucune autre modification à faire ailleurs dans le programme. Les autres parties du programme n'ont pas à savoir ce qui se passe à l'intérieur de l'objet.
La façon dont j'organise les choses à l'intérieur de l'objet, c'est l'implémentation. La manière dont se présente une méthode, c'est sa déclaration. Je peux donc modifier une méthode (son implémentation, sa définition) sans modifier la façon dont elle se présente à ceux qui vont l'utiliser (sa déclaration).
Pour créer un objet, il faut d'abord faire un plan de cet objet. À partir de ce plan, je pourrai alors créer des objets avec l'opérateur new. Le plan c'est la classe.