Notions d'objet, de classe

 
 

La programmation procédurale: caractéristiques.

Des langages typés.

                Lorsque nous déclarons:

                    int n;

        nous utilisons un type de base du langage C; nous déclarons un identificateur -n- et indiquons que la valeur prise par cette variable est de type entier. Grâce à ce typage nous pourrons utiliser les opérations prévues pour ce type.

Des Types Definis par l'Utilisateur -TDU- exemple en C

    La plupart des langages procéduraux offrent la possibilité de déclarer des types définis.
Ainsi en C les structures jouent ce rôle:

    struct Produit
    {
     string nom;
    float prix;
    int qte_stock;
    };

    La déclaration de variables de type Produit peut prendre deux formes :

        Déclaration d'une variable du type.

                                Produit p;
               

 p est ainsi de type Produit et pourra être valorisé par:

                        p.nom = "Pomme";
                        p.prix = 10;
                        p.qte_stock = 500;

        Déclaration d'une référence sur l'objet.

                        p * Produit;

                        p = new Produit;

                p n'est pas ici l'objet mais sa référence. La valorisation de l'objet part de sa référence.

                         p->nom = "Pomme";
                        p->prix = 10;
                        p->qte_stock = 500;

                A noter que puisque nous ne manipulons jamais l'objet lui-même, le problème de sa destruction se posera.

Des procédures pour manipuler les données.

        Si nous voulons effectuer des traitements sur les données, nous déclarons à côté des TDU des procédures utilisant ces variables
en paramètres, intéressons nous simplement aux signatures des fonctions:

            void InitProduit ( produit & p,string,int,int);
            void AfficheProduit( produit p);
           void DestockeProduit( produit & p, int nb);

 

            On constate que ces fonctions utilisent explicitement des TDU - ou leurs références - présents dans les paramètres. Dans l'organisation des programmes ceci se traduit par une séparation des données et des traitements.
 

prog structuree
 

        Remarque: nous utilisons dans ce modèle la relation de dépendante -UML - symbolisée par une flèche orientée en pointillé.
 

        Cette séparation entre les structures de données et les procédures n'est pas sans poser des problèmes, par exemple qu'advient-il si nous "oublions" de valoriser un produit par InitProduit. ( pour "plus" cf le langage C++). Et surtout cette programmation se heurte à un problème de réutilisabilité du code; si nous voulons créer un type ProduitFrais, il est certes possible d'écrire:

            struct ProduitFrais
            {
                produit leproduit;
                int duree_validité;
            };

        mais alors, il nous faut modifier toutes les procédures alors que, par exemple, DestockeProduit n'a pas besoin de l'être.

                                                 Notion d'objet

            Le monde qui nous entoure est constitué d'objets. Ma voiture, le livre qui est sur la table, le film que l'on vient d'aller voir. Ce qui justifie les "contours" de l'objet dépend du domaine d'étude, ceci relève de la responsabilité de l'analyste. Par définition, un objet est unique, un livre identique à celui qui est sur la table est un autre livre.

                   Attributs des objets.

    Le livre comporte un nombre de pages, un poids, un titre... Cela traduit l'état de l'objet à tout moment.. Une personne a une taille, un poids, une couleur de peau ...Ces attributs sont susceptibles de changer de valeur, le poids d'une personne évolue sans cesse. Certains attributs par contre ne verront pas leurs valeurs évoluer, la couleur de la peau par exemple.

    Les attributs d'un objet permettent de connaître les informations sur l'objet.
 

                    Comportement des objets, messages.

    L'objet n'est  pas seulement une somme d'informations, l'objet réagit. Cela n'est possible que s'il est muni d'opérations - actions-  qui seront déclenchées en réponse à des sollicitations extérieures - d'un autre objet -. On traduit ce processus en introduisant la notion de message; la réception d'un message va engendrer la réaction de l'objet. Bien sûr il faut que l'objet possède dans son comportement une action capable de traiter le message.

    Ainsi un train  peut recevoir des messages stopper, ralentir, accélérer, des actions spécifiques seront déclenchées, par contre le message voler sera rejeté

 

Remarque: nous utilisons quatre éléments impruntés d'UML.

            - Un objet est représenté par un rectangle, son nom est souligné:

            - Le message est représenté par une flèche orienté.

            - Le trait liant les deux objets symbolise une relation.

            - La note représentée par un rectangle corné permet de préciser une notion.
 
 

    Le message a un nom,  un émetteur, et un destinataire. A noter que le nom du message correspond en général au nom de l'action qui va être déclenchée par l'objet récepteur du message, néanmoins il faut avoir à l'esprit qu'il s'agit de deux processus différents: un objet reçoit un message et réagit par l'exécution d'une action.
    Cette distinction est bien visible dans les langages événementiels. Ainsi un bouton qui reçoit un événement Click - message - va réagir en exécutant le code qui se trouve dans la méthode Click des boutons
 

    Le comportement d'un objet est ainsi la somme de ses actions.

    Si un objet déclenche une action, cela produit une modification de son état, ainsi l'action "Accélérer" va modifier la valeur de son attribut "Vitesse". De même l'état d'un objet influence son comportement. Le message "Stopper" ne sera pas accepté si l'état de l'attribut "en marche" est à faux.

                            Identité et identifiant.

    Nous avons vu qu'un objet est unique, il a donc une identité; la notion d'identifiant ne relève pas du domaine de l'analyse mais de celui de l'implémentation - réalisation- .Bien sûr rien, n'interdit de faire figurer un attribut, comme un numéro de SS, mais simplement par soucis de description de l'objet et non d'identification.
 
 

                                         Notion de classe.

    Si la notion d'objet est le point de départ, il est nécessaire d'imaginer un niveau conceptuel qui permette de regrouper  les objets  selon leur comportement et leurs attributs. Ainsi une classe va rassembler les objets de même nature.

                   Représentation d'une classe.

 

        Une classe avec UML est représentée par un rectangle, sa partie haute est réservée à son nom, la zone du milieu contient les attributs et la partie basse les opérations.
 

Exemples

    En programmation objet, les opérations sont appelées méthodes.

    En utilisant le langage algorithmique, nous pouvons écrire:

    Classe Train
            Attributs:
                Vitesse : Reel
                EnMarche : Booleen
            Méthodes:
                Procédure Stopper()
                Procédure Ralentir( Donnée v : Entier )
                Procédure Accélerer( Donnée v : Entier)
    FinClasse

         Un objet est une instance d'une classe.

        untrain : Train

          Après son instanciation l'objet bénéficie du comportement et des attributs de sa classe.

            untrain.Ralentir( 50 )
            untrain.Stopper()

 
            Notez la syntaxe:                <Nom de l'objet>.<Méthode
 
 

                             Retour sur les messages.
 

    Interprétons l'envoi par un conducteur d'un message Stopper en direction d'un train:

   Classe Train
            Attributs:
                Vitesse : Reel
                EnMarche : Booleen
            Méthodes:
                Procédure Stopper()
                Procédure Ralentir( Donnée v : Entier )
                Procédure Accélerer( Donnée v : Entier)
    FinClasse

    Classe conducteur
        Attributs:
           ...
        train  montrain;
        Méthodes:
         Procédure  ArreterLeTrain()
                     montrain.Stopper()
        FinProcédure
 
 

       Un conducteur envoie le message Stopper à son train, mais c'est de la responsabilité du train de s'arrêter, de plus le conducteur n'a pas besoin de savoir comment le train s'arrête. Les objets des deux classes communiquent à l'aide de messages, chaque objet de classe traitant les messages qu'il reçoit.
 

                          Statuts des attributs et opérations

    Les attributs et méthodes sont associés à des indicateurs de visibilité. Ces indicateurs sont très utiles pour cacher à l’utilisateur la représentation du type de l’objet ainsi que les procédures et fonctions non concernées par les spécifications.
    Généralement on compte trois niveaux de visibilité - du plus restrictif au plus accessible :

Privé (private)  : rend l'élément visible à la classe seule.
Protégé (protected) : rend l'élément visible aux sous-classes de la classe (la notion de      sous-classe sera abordée avec l'héritage)
 Public :   rend l'élément visible à tout client de la classe.

    Le niveau de visibilité est symbolisé par les caractères +, # et -, qui correspondent respectivement aux niveaux public, protégé, et privé (notation utilisée par la méthode UML).

               La nouvelle représentation devient:

                                                                                                                   

    L'encapsulation représente un des concept fondamentaux du monde objet. Par principe même, on ne peut accéder aux attributs ou opérations d'un objet en dehors de ceux explicitement déclarés public par la classe. Ainsi une classe n'est utilisable qu'au travers son interface - ensemble des attributs et opérations publics
    . Une recommandation forte impose de ne pas déclarer les attributs publics.

        Par exemple,  nous ne pourrons pas écrire:

            Procédure  ArreterLeTrain()
                     montrain.Vitesse = 0
            FinProcédure

    La donnée vitesse est encapsulée dans la classe Train, elle n'est pas accessible directement.