Intéressé par des cours d'informatique en ligne ?
Visitez mon nouveau site https://www.yesik.it !

Cet article est une reprise de l'article Introduction aux objets que j'avais précédemment publié sur http://wiki.esicom-st-malo.fr

Si vous demandez à un informaticien chevronné ce qu'est un objet, il va d'abord vous regarder avec des yeux ronds, puis, après quelques secondes de silence, vous donner une réponse laconique du genre "Un objet? Ben, ça peut être n'importe quoi dans un programme...".

Cet article tente de démystifier ce sujet - bien moins compliqué que les débutants ne le croient - et répondre à la question c'est quoi un objet?

Avant de commencer

Les exemples dans cet article sont écrits en Java. Il n'est pas nécessaire d'avoir une grande expérience de la programmation dans ce langage pour comprendre ce qui est dit ici. Tout au plus, il vous faut connaître un peu la syntaxe et savoir compiler un programme Java. Si vous savez écrire un "Hello World" en Java, c'est largement suffisant.

Analogie avec le monde réel

Avant de nous lancer dans des explications "pour informaticien", nous allons tout d'abord observer un peu ce qui se passe dans le monde réel. Cela va nous permettre d'introduire plusieurs notions clés - et le vocabulaire correspondant.

Le monde réel est plein d'objets, avec lesquels nous interagissons et qui interagissent entre-eux. Prenons un exemple très simple: Imaginons que je veuille écouter un peu de musique. Je prends donc mon poste de radio, et j'appuie sur le bouton marche de celui-ci. J'ai pris un objet (le poste de radio) et j'ai fait une action dessus (le mettre en marche).

Note:

Une des difficultés en programmation orientée objets, c'est que le même concept peut avoir plusieurs noms différents. Ainsi, on rencontre parfois le terme opération plutôt qu'action.

Lors de la mise en œuvre (avec un langage de programmation), on parlera plutôt de méthodes ou de fonctions membres.

Bien entendu, un même objet peut supporter plusieurs actions. Outre mettre en marche mon poste de radio, je peux aussi l'arrêter, changer de station, ou régler le volume. L'ensemble des actions qui peuvent être effectuées sur un objet définit son comportement.

Ainsi, à un moment donné, mon poste de radio est réglé sur une station, et diffuse de la musique à un certain volume. Ces caractéristiques sont appelées les attributs de mon objet. Chaque attribut peut prendre une valeur et l'ensemble des valeurs des attributs définissent l'état d'un objet.

Note:

Une des difficultés en programmation orientée objets, c'est que le même concept peut avoir plusieurs noms différents (déjà vu?). Ainsi, plutôt que de parler d'attributs, on parle parfois de propriétés.

Lors de la mise en œuvre (avec un langage de programmation), on parlera plutôt de données membres, de variable membres, de variables d'instance ou encore de champ.

Diagramme UML de la classe Radio avec 4 méthodes et 2 attributs.

Imaginons maintenant que vous disposiez également d'une radio - du même modèle que la mienne. Évidemment, puisqu'elles sont du même modèle, votre radio et la mienne ont le même comportement et possèdent les mêmes attributs (volume, réglage station). Deux objets qui ont le même comportement et possèdent les mêmes attributs appartiennent à la même classe.

Deux objets appartiennent à la même classe

  • S'ils ont le même comportement
  • et s'ils ont les mêmes attributs.


Note:

Bien entendu, même si elles appartiennent à la même classe (au même modèle), rien n'empêche votre radio d'être réglée sur une station différente de la mienne. Leurs états peuvent tout à fait être différents!

Diagramme d'objets UML représentant deux instances de la classe Radio. Chaque instance possède ses propres valeurs pour les attributs.

Le tout dernier concept qui nous reste à voir est celui d'identité. Il va de soit que même si les réglages de votre radio et ceux de la mienne sont parfaitement identiques (en d'autre termes, si leurs états sont identiques), ces deux radio restent néanmoins des objets distincts. Elles sont pourtant du même modèle (de la même classe). Le volume et la station sont réglés à l'identique (elles sont dans le même état). Et pourtant elles existent toujours indépendamment l'une de l'autre. On dit qu'elles ont chacune une identité différente. Chaque nouvel objet créé à partir d'une classe est appelé une instance de cette classe.

un objet est parfaitement définit par:

  • son identité (cette radio la)
  • sa classe (de tel modèle)
  • et son état (avec ces réglages).


Dans le contexte informatique

La plupart des programmes informatiques ne contiennent pas de postes de radio et ne servent pas à changer de station ou monter le volume.

Par contre, ils sont pleins de comptes bancaires, de clients, de factures, d'utilisateurs, de boîtes de dialogues, etc. Vous l'avez compris, toutes ces "choses" seront en fait des objets du programme.

En règle générale, tout ce qui peut se définir par un nom commun est un bon candidat pour devenir un objet (Voir "Du besoin au programme Java").

Pour illustrer notre propos en Java, nous allons essayer de modéliser un "objet" du monde réel: un employé. Un tel objet pourrait servir, par exemple dans un programme de gestion administrative d'une entreprise.

Définir la classe

La première étape à réaliser va être de définir la classe des "employés", c'est à dire l'ensemble des attributs que chaque employé peut avoir, et les actions qu'on peut lui appliquer.

La classe Employe

Dans notre exemple, chaque employé possède:

Et avec un employé, on peut:

Nous allons résumer toutes ces informations dans le fichier Employe.java

/* La classe des employés */
public class Employe
{
    /* attributs */
    private String nom;
    private String prenom;
    private int echelon;
 
    /* méthodes */
    public void affiche() {
        System.out.println(nom + " " + prenom + " " + echelon); 
    }
 
    public void donnePromotion() {
        echelon = echelon+1;
    }
}

Attention aux accents

Le fichier s'appelle Employe.java pas Employé.java. Et la classe Employe pas Employé!

Vous pouvez compiler cette classe avec la commande suivante (le sh$ n'est pas à taper: il représente l'invite de votre shell):

sh$ javac Employe.java

S'il n'y a pas d'erreur de compilation, félicitations, vous avez créé votre première classe. Mais nous n'avons pas encore d'objets!

Instancier un objet

Pour créer les objets, il va falloir aller dans une autre partie du programme (dans une autre classe) et demander la création de nos employés.

Remarque:

Vous vous demandez peut-être pourquoi on ne peut pas créer les employés dans la classe Employe? Et bien, à nouveau, nous pouvons utiliser l'analogie avec le monde réel: ma radio ne s'est pas créée toute seule. Elle a été fabriquée par une usine. Et l'usine, en terme informatique, c'est aussi un objet. Un objet d'une classe différente de celle de ma radio, mais un objet quand même. On a bien un objet d'une classe qui crée un objet d'une autre classe!

La création se fera dans le fichier Programme.java

public class Programme {
    public static void main(String[] args) {
        Employe         john = new Employe();
        Employe         paul = new Employe();
        Employe         jack = new Employe();
    }
}

Remarque:

Ce programme Java ressemble fort à ce que vous avez réalisé si vous avez suivi le tutoriel "Hello World" du site de Sun: en fait, tous les programmes Java possèdent une classe de ce style, avec une méthode main: c'est le programme principal. C'est par là que commence l'exécution de votre programme.

La grosse différence ici avec un programme de style "Hello World", c'est qu'au lieu d'afficher des choses, on crée des objets de la classe Employe.

Vous pouvez compiler et exécuter ce programme:

sh$ javac Programme.java
sh$ java Programme

Rien de visible ne se passe: en effet, notre programme crée bien trois employés, mais n'en fait rien. Nous allons le modifier pour demander à chaque employé d'afficher les infos le concernant:

public class Programme {
    public static void main(String[] args) {
        Employe         john = new Employe();
        Employe         paul = new Employe();
        Employe         jack = new Employe();
 
        john.affiche();
        paul.affiche();
        jack.affiche();
    }
}

Nous pouvons à nouveau compiler et tester:

sh$ javac Programme.java
sh$ java Programme
null null 0
null null 0
null null 0

Pas très concluant? Et pourtant, c'est normal: nous avons défini la classe des employés. Puis nous avons instancié trois employés différents (chaque new crée un nouvel objet avec sa propre identité). Par contre, nos objets n'ont pas d'état. Ou plutôt ont un état par défaut donné par Java ("tout à 0") qui ne nous convient absolument pas!

Fixer l'état initial

La solution mise en œuvre en Java pour définir l'état de départ d'un objet est d'utiliser un constructeur. Il s'agit de code exécuté lors de la création de chaque objet d'une classe. Revenons dans le fichier Employe.java et faisons les modifications suivantes:

/* La classe des employés */
public class Employe
{
    /* attributs */
    private String nom;
    private String prenom;
    private int echelon;
 
    /* constructeur */
    public Employe(String nomInitial,
                   String prenomInitial, 
                   int echelonInitial) {
        nom = nomInitial;
        prenom = prenomInitial;
        echelon = echelonInitial;
    }
 
    /* méthodes */
    public void affiche() {
        System.out.println(nom + " " + prenom + " " + echelon);
    }
 
    public void donnePromotion() {
        echelon = echelon+1;
    }
}

Le constructeur n'est pas une méthode!

Une méthode représente une action qui peut être effectuée sur un objet. Or le constructeur sert à fixer l'état initial de l'objet. Conceptuellement, l'objet n'existe pas avant l'exécution du constructeur. Par conséquent le constructeur n'est pas une méthode!

Maintenant, notre classe possède un constructeur qui fixe l'état de départ de l'objet. Bien entendu, le constructeur ne peut deviner les valeurs nomInitial, prenomInitial et echelonInitial. Il est obligatoire de les fournir lors de la création des objets.

Retour donc à Programme.java qui devient:

public class Programme {
    public static void main(String[] args) {
        Employe         john = new Employe("Doe", "John", 1);
        Employe         paul = new Employe("Smith", "Paul", 3);
        Employe         jack = new Employe("Robs", "Jack", 9);
 
        john.affiche();
        paul.affiche();
        jack.affiche();
    }
}

A nouveau compilons (les deux fichiers) et testons:

sh$ javac Employe.java
sh$ javac Programme.java
sh$ java Programme
Doe John 1
Smith Paul 3
Robs Jack 9

Et voilà, nous avons créé 3 objets de la même classe!

Vérification

Pour illustrer le fait que deux objets avec le même état restent tout de même distincts, nous allons utiliser le programme suivant:

public class Programme {
    public static void main(String[] args) {
        Employe         empl1 = new Employe("Smith", "John", 1);
        Employe         empl2 = new Employe("Smith", "John", 1);
 
 
        empl1.affiche();
        empl2.affiche();
        empl2.donnePromotion();
        System.out.println("Après promotion");
        empl1.affiche();
        empl2.affiche();
    }
}

Ce programme effectue les opération suivantes:

  1. Création de deux employés avec le même état initial;
  2. Affichage de l'état des deux employés;
  3. Promotion de l'employé empl2;
  4. Affichage de l'état des deux employés.

Le résultat est donné ci-dessous:

Smith John 1
Smith John 1
Après promotion
Smith John 1
Smith John 2

Comme vous le constatez, à un moment les deux employés avaient bien le même état, mais ils sont quand même resté deux objets distincts. La promotion accordée à l'employé empl2 n'a eu absolument aucune influence sur l'employé empl1.