La programmation orientée objet

Un bref historique

    • Simula
      • Créé en 1962 par Ole-Johan Dahl et Kristen Nygaard
      • Langage de simulation
      • Basé sur Algol60, un langage procédural utilisé dans les années 1960
      • L’invention du concept objet par accident
      • L’objectif du langage était de simuler des objets de la vie réelle.
      • Même s’il s’agit du premier langage-objet, son implémentation objet est chaotique et mal structurée.
    • Smalltalk
      • Créé en 1972 par Alan Kay, Dan Ingals, Ted Kaehler, Adele Goldberg
      • L’objectif du langage est la transmission de message entre instances d’objet.
      • Basé sur Simula
      • Langage par prototype.
      • Alan Kay est souvent considéré comme un des pères de la programmation orientée objet 2.
    • C++
      • Créé en 1983 par Bjarne Stroustrup
      • Évolution orientée objet du langage C
      • Structure objet puissante, mais mal structurée.
        • Certains programmeurs C++ se réfugient dans les « template » C++ pour éviter les problèmes que peut poser la structure objet C++.
        • Certains programmeurs évitent d’utiliser certains concepts objet C++ (par exemple, l’héritage multiple) afin d’éviter les problèmes que peut poser la structure objet C++
    • Eiffel
      • Créer en 1986 par Bertrand Meyer
      • les langages orientés objet de l’époque étaient souvent mal structurés et malgré que beaucoup de bonnes idées ressortaient, le domaine était pour le moins, chaotique.
      • Bertrand Meyer, un chercheur en développement logiciel, écrivit un livre sur le développement de langage orienté objet:
        • Object-Oriented Software Construction
      • Aucun langage à l’époque ne permettait de gérer tous les concepts objets présentés dans le livre;
      • Bretrand Meyer a donc inventé un langage théorique (à l’époque) qui lui permettrait de donner les démonstration et exemple nécessaire dans son livre.
      • Bertrand Meyer est également considéré comme un des pères de la programmation orientée objet.
    • Java:
      • Créé en 1996 par Sun Microsystem.
      • L’objectif était de créer des programmes orientés objet pour le Web
      • Contrairement aux langages orientés objet de l’époque (C++, Ada, Pascal, etc.), Java obligeait l’utilisation de l’orientée objet dans la création de code.
      • Malgré qu’il n’a apporté aucune évolution aux mécaniques objets, java a grandement participé à l’intérêt des développeurs pour les technologies objet.

Un objet

Un objet est une représentation abstraite d’une instance mémoire permettant de regrouper des informations reliées entre elles par des liens logiques et des mécanismes permettant la manipulation de ces informations.

Comparaison avec la programmation procédurale

Comme on peut le constater dans la définition, la programmation orientée objet met de l’avant les informations avant les mécanismes. Inversement, la programmation procédurale met au premier plan les mécanismes (les routines) et les informations interviennent d’une certaine manière en support à ces mécanisme. Il s’agit d’un changement de paradigme majeur.

Les classes

Une classe est une définition des caractéristiques communes d’un ensemble d’objets. Elle contient, entre autres, l’ensemble des attributs et des déclarations de méthodes que ces objets ont en commun.

Voici la syntaxe d’une classe en Java:

public class Personne {
    ...
}

Cet exemple représente une classe publique. Une classe publique doit être placée dans son propre fichier et le nom du fichier doit être le même que le nom de la classe, sans prendre en compte l’extension « .java ». Par exemple, dans l’exemple précédent, le fichier qui contient cette classe devrait s’appeler « Personne.java ».

Instanciation

On dit qu’un objet est une instance de classe. Il est important de bien saisir la nuance entre une classe et un objet. En comparaison, vous pouvez voir la classe comme étant une recette de cuisine et l’objet comme étant le plat créé grâce à cette recette. Par exemple, si notre classe est une recette de gâteau, chaque gâteau sera une instance de cette classe. On peut voir qu’avec la même recette de gâteau, il est possible de faire une grande quantité de gâteau différent (couleur, décoration, etc.) De la même manière, une classe peut être utilisée afin de générer plusieurs objets différents (avec des valeurs différentes). Par exemple, une classe « Personne » contenant un « nom » et un « prenom » pourrait être utilisé pour créer les trois objets différents: « Louis Marchand », « Elon Musk » et « Chuck Norris ».

En java, on utilise le mot clé « new » pour instancier un objet:

Personne lPersonne = new Personne();

Dans cet exemple, nous instancions un objet basé sur la classe « Personne » et nous assignons cet objet à la variable « lPersonne ».

Les attributs

On appelle attribut d’un objet une information qui spécifie une caractéristique d’un objet. L’ensemble des attributs d’un objet permet de caractériser précisément l’état d’un objet.

En java, les attributs sont déclarés de la même manière qu’une variable, mais à l’extérieur d’une routine. Par exemple:

public class Personne {
    public String nom;

    public String prenom;
}

Dans cet exemple, la classe « Personne » a 2 attributs: « nom » et « prenom ». Pour l’instant, nous allons tous mettre publique. Mais dans une future théorie, nous allons voir qu’il ne faut pas déclaré un attribut publique. Nous utilisons des attribut publique ici afin de pouvoir tester nos classes de base, sans avoir à créer des structures plus complexe.

Les méthodes

On appelle méthode d’un objet une routine s’appliquant à cet objet en particulier.

En java, puisqu’une méthode est une routine, les méthodes sont déclarées de la même manière que les routines. Par exemple:

public class Personne {
    public String nom;

    public String prenom;

    public String nomComplet(){
        return prenom + " " + nom;
    }

    public void bonjour(){
        System.out.println("Bonjour " + nomComplet());
    }
}

On voit que ma classe « Personne » a deux (2) méthodes: « nomComplet » qui est une fonction et « bonjour » qui est une procédure.

Le type d’un objet

Le type d’un objet représente la classe (ou le type primitif) utilisée dans la déclaration de la variable contenant cet objet. Par exemple, dans le code suivant:

Personne lPersonne;

L’objet (et la variable) lPersonne est de type Personne.

Liens client/fournisseur

Les clients d’une classe

On dit qu’une classe A est client d’une classe B si un attribut ou une fonction de la classe A retourne un objet ou un ensemble d’objets de type B.

Il est à noter que, par simplicité, on élargit parfois cette définition afin d’y inclure tous les variables locales et arguments de méthodes.

Par exemple, dans le code java de « Personne » présenté plus haut, la classe « Personne » est client de la classe « String » puisque deux (2) attributs sont de type « String » et une méthode retourne un objet de type « String ».

Les fournisseurs d’une classe

On dit qu’une classe A est fournisseur d’une classe B si un attribut ou une fonction de la classe B retourne un objet ou un ensemble d’objets de type A. En d’autres mots, un lien fournisseur est l’inverse d’un lien client.

Donc, dans le code java de « Personne » présenté plus haut, la classe « String » est fournisseur de la classe « Personne ».

Les constructeurs

Un constructeur est une procédure spéciale de la classe. Son objectif est d’initialiser l’état de l’objet. En général, ça signifie initialiser les attributs de l’objet. Cette procédure est appelée lors de l’instanciation de l’objet (en java, lorsqu’un « new » est utilisé).

Il y a une règle d’or en programmation orientée objet disant que les constructeurs de chaque classe ont comme responsabilité d’initialiser tous les attributs de cette classe. En d’autres mots, s’il y a des attributs dans une classes, il devrait normalement y avoir au moins un constructeur qui initialise ces attributs. Un attribut ne devrait pas rester non initialisé après l’instanciation d’un objet. Il est par contre possible d’initialiser un attribut avec une valeur NULL (une variable est dit NULL lorsque celle-ci ne contient aucun objet).

En java, le constructeur est nommé avec le même nom de la classe et n’a aucun type de retour (même pas void). Il est possible d’avoir plusieurs constructeurs, pourvu que la signature de chaque constructeur soit différente. En d’autres mots, chaque constructeur doit avoir des arguments de types différents.

Par exemple:

public class Personne {

    public String nom;

    public String prenom;

    public Personne(){
        nom = "";
        prenom = "";
    }

    public Personne(String aNom, String aPrenom){
        nom = aNom;
        prenom = aPrenom;
    }

    public String nomComplet(){
        return prenom + " " + nom;
    }

    public void bonjour(){
        System.out.println("Bonjour " + nomComplet());
    }
}

On voit que dans cette classe, nous avons 2 constructeurs. Un constructeur ne prenant aucun argument et un constructeur ayant deux (2) arguments (« aNom » et « aPrenom »).

Pour utiliser les constructeurs différents, il faut envoyer le bon nombre et bons types d’arguments lors de l’exécution du « new ». Par exemple, pour utiliser le constructeur sans argument, nous utilisons:

Personne lPersonne = new Personne();

et pour utiliser le constructeur avec 2 arguments, nous utilisons:

Personne lPersonne = new Personne("Marchand", "Louis");

Limitation

Il est à noter qu’il existe certaines limitations avec le système de constructeurs de Java. Une limitation importante, c’est qu’il est impossible d’avoir plusieurs constructeurs différents avec le même nombre d’arguments de même type dans le même ordre. Par exemple, ce code ne fonctionnera pas:

public class Personne {

    public String nom;

    public String prenom;

    public Personne(){
        nom = "";
        prenom = "";
    }

    public Personne(String aNom){
        nom = aNom;
        prenom = "";
    }

    public Personne(String aPrenom){
        nom = "";
        prenom = aPrenom;
    }

    public Personne(String aNom, String aPrenom){
        nom = aNom;
        prenom = aPrenom;
    }

    public String nomComplet(){
        return prenom + " " + nom;
    }

    public void bonjour(){
        System.out.println("Bonjour " + nomComplet());
    }
}

En effet, puisque la classe a deux (2) constructeurs avec la signature: « public Personne(String) », il n’y a aucune manière pour le compilateur Java de savoir quel constructeur utiliser dans le code:

Personne lPersonne = new Personne("Martin");

Appeler un constructeur à partir d’un autre constructeur

Tout comme il est possible d’appeler n’importe quelle méthode de la classe à partir d’un constructeur, il est également possible d’appeler un autre constructeur. Pour appeler un constructeur à partir d’un autre constructeur, on utilise la syntaxe: « this(…) » (ou les trois points représentent les arguments à envoyer au constructeur).

Par exemple, le code de « Personne » ci-haut (avec 2 constructeurs) est équivalent à ce code:

public class Personne {

    public String nom;

    public String prenom;

    public Personne(){
        this("", "");
    }

    public Personne(String aNom, String aPrenom){
        nom = aNom;
        prenom = aPrenom;
    }

    public String nomComplet(){
        return prenom + " " + nom;
    }

    public void bonjour(){
        System.out.println("Bonjour " + nomComplet());
    }
}

En effet, on voit qu’au lieu d’assigner les chaînes de caractères vides directement dans le constructeur « Personne() », ce dernier appel le constructeur « Personne(String aPrenom, String aNom) » avec comme arguments les chaînes vides.

Diagramme de classe

Dans le standard UML, on appelle diagramme de classe un diagramme permettant de représenter, de manière visuelle, le « desing » des classes du système à développer.

Dans un diagramme de classe, une classe est présentée comme une boite contenant 3 sections horizontales: une pour le nom, une pour les attributs et une pour les méthodes et constructeurs.

Les liens clients/fournisseurs peuvent se faire de différente façon. Afin de garder ces diagrammes simple dans le cadre du cours, nous allons présenter ce type de liens avec une flèche (avec une pointe vide et non fermée). La direction du lien se fait à partir du fournisseur vers le client.

Vous pouvez voir que j’ai utilisé le nom de méthode « nom_complet » et non « nomComplet ». Il est important de considérer un diagramme de classe comme étant indépendant du langage à utiliser. Donc, il n’est pas nécessaire de respecter le standard du langage.

Retour

 


Auteur: Louis Marchand
Creative Commons License
Sauf pour les sections spécifiées autrement, ce travail est sous licence Creative Commons Attribution 4.0 International.