POURQUOI CE BLOG, POUR QUI ?


POURQUOI CE BLOG, POUR QUI ?
Ce Blog s'adresse à tous ceux qui sont passionnés par les sciences informatiques , Professionnels,Etudiants,Amateurs ...
Les sujets exposés dans la suite se rapporteront essentiellement sur l'analyse informatique,la programmation,le développement ainsi que à l'architecture IT.
QUI SUIS JE ?
Je suis Kangulungu Lubilanji, Consultant-Freelance sur les technologies .NET,C#,ASP.NET ... Contactez moi pour plus d'informations.

La Programmation OO: Chapitre 4. Les objets parlent aux objets

Chapitre 4.  Les objets parlent aux objets
Ce chapitre illustre et décrit le mécanisme d'envoi de messages qui est à la base de l’interaction entre les objets. Cette interaction exige que les classes dont sont issus ces objets entre dans un rapport de composition, d'association ou de dépendance.

Envois de message, les objets interragissent, et comme tout ce qu'ils font dit être prévu dans leurs classes, celles-ci se doivent d'interagir également. C'est cette interaction entre objets, lorsqu'un d'entre eux demande à l'autre d'exécuter une méthode, qui constitue le mécanisme clé et récurrent de l'exécution d'un programme OO. Un tel programme n'est finalement qu'une longue suite d'envois de message entre les objets agrémentés ici et là de quelques mécanismes procéduraux (tests conditionnels, boucles ...).

Nous allons, à l'aide d'un exemple minimal de programmation, illustrer ce principe de communication entre deux objets. Supposons un premier objets o1, instance d'une classe01, contenant la méthode jeTravaillePour01( ), et un deuxième objet o2, contenant la méthode  jeTravaillePour02( ). Dans le logiciel, o1 interagira avec o2, si la méthode jeTravaillePour01( ) contient un instruction pour que l'objet o1 interfére avec l'objet o2. Mais, pour que o1 puisse exécuter quoi que ce soit, il faudra d'abord chercher la méthode jeTravaillePour01( ) sur o1. Nous supposerons que la méthode main s'en charge et débute l'exécution du programme en déclenchant la méthode jeTravaillePour01( ) sur l'objet o1. Comme ci-dessous.
Dans ce diagramme (il s'agit en fait d'un diagramme de séquence UML), le petit bonhomme fait office de main, en envoyant le premier message jeTravaillePour01( ) sur l'objet o1. Par la suite, nous voyons que l'objet o1 interrompt l'exécution de sa méthode, le temps pour o2 d'exécuter la sienne. Finalement le programme reprendra normalement son cours, là où il l'a abandonné, en redonnant la main à o1. L'envoi de message s'accompagne d'un passage de relais de l'objet o1 à l'objet o2, relais qui sera restitué à o1 une fois qu'o2 en aura terminé avec sa méthode.

Association de classes, Si o1 déclenche la méthode jeTravaillePour02( ) sur l'objet o2, c'est que la classe responsable de o1 sait que cet objet o2 est à même de pouvoir exécuter cette méthode. Pour ce faire, la classe o1 se doit d'être informée, quelque part dans son code, sur le type de l'objet o2, c'est-dire la classe o2. Une première manière pour la classe o1 de connaître la classe o2 est celle indiquée ci-dessous(il s'agit à nouveau d'un diagramme UML, cette fois de classe).
On dira dans ce cas que les deux classes sont associées et que la connaissance de o2 devient une donnée structurelle à part entière de la classe o1. En langage de programmation, o2 devient purement et simplement le type d'un attribut de o1, comme dans le code de la classe qui suit :  
class 01{
    02 lien02 ; /* la classe 02 type un attribut de la classe 01 */
    void jeTravaillePour01() {
        lien02.jeTravaillePour02() ;
    }
}
Comme tout autre attribut de type « primitif », cet attribut lienO2 devient accessible dans l'entièreté de la classe. Il s'agit en fait d'une espèce nouvelle d'attribut dit « attribut référent », typé, non plus par un type primitif, mais bien par la classe qu'il réfère. Dans l'espace mémoire réservé à o1, l'attribut lienO2  contiendra,   l'adresse de l'objet o2. C'est qui lui permettra d'entrer directement en communication avec o2.
La manière privilégiée pour permettre à deux classes de communiquer par envoi de message consiste  à rajouter aux attributs primitifs de la première un référent du type de la seconde. La classe peut donc, tout à la fois, contenir des attributs et se constituer en nouveau type attribut. C'est grâce à ce mécanisme de typage particulier que, partout dans son code, la première classe pourra faire appel aux méthodes disponibles de la seconde.
Dépendance de classes, il existe d'autres manières, non persistantes cette fois, pour la classe 01de connaître le type 02. Comme dans le code qui suit, la méthode jeTravaillePour01(02 lien02) pourrait recevoir comme argument l'objet o2, sur lequel il est possible de déclencher la méthode jeTravaillePour02( ).
class 01{
    void jeTravaillePour01(02 lien02) {
        lien02.jeTravaillePour02() ;
    }
}
Le compilateur acceptera le message car le destinataire est bien typé par la classe 02. Cependant, dans un cas semblable, le lien entre 01 et 02 n'aura d'existence que le temps d'exécution de la méthode jeTravaillePour01( ), et on parlera, entre les deux classes, plutôt que d'un lien d'association, d'un lien de dépendance, plus failble et surtout passager. Dans le diagramme de classe UML, le lien passe de « plein » à « pointillé ».
Les deux classes ne connaissent dès lors que durant le temps d'exécution de la méthode. Un lien de dépendance est maintenu entre les deux classes, car toute modification de la classe qui fournit la méthode à utiliser pourrait entraîner une modification de la classe qui fait appel à cette méthode. Il s'agit à proprement parler plutôt d'une dépendance  de type logicielle, car elle reste au niveau de l'écriture logicielle des deux classes, alors que le lien d'association va bien au-delà de cette dépendance, et représente une véritable connexion structurelle et fonctionnelle entre ces deux classes.

Un autre liaison passagère pourrait se produire, si, comme dans le code ci-après la méthode jeTravaillePour01( ) décide, tout de go, de créer l'objet lien02, le temps de l'envoi du message.
class 01{
    void jeTravaillePour01() {
    02 lien02 =  new 02
        lien02.jeTravaillePour02() ;
    }
}
Au sortir de la méthode, l'objet lien02 sera irrémédiablement perdu, de même que cette liaison passagère qui, là encore, n'aura duré que le temps d'exécution de la méthode jeTravaillePour01( ).En Java et C# le seul référent étant à nouveau stocké en mémoire pile, la méthode terminée, ce référent disparaîtra emportant à sa suite le seul objet référé par lui.Alors que, dans le première dépendance, c'est la liaison entre les deux objets qui s'interrompait à la fin de la méthode, ici l'objet du message s’éclipsera également à la fin de cette méthode.Autant que faire se peut, on privilégiera entre les classes des liens de type fort, d'association, faisant des relations entre les classes une donnée structurelle de chacune d'entre elles.
Communication possible entre objets, deux objet pourront communiquer si les deux classes correspondantes possèdent entre elles une liaison de type composition, association, ou de dépendance, la force et la durée de la liaison allant décroissant avec let type de liaison. La communication sera dans les  liaisons de type composition et ou association possible, quelle que soit l'activité entreprise par le premier objet, alors que dans  les  liaisons de type dépendance elle se déroulera uniquement durant l'exécution des seules méthodes du premier objet, qui recevront de façon temporaire un référent du second.


La Programmation OO: Chapitre 3. Du procédural à l'OO

Chapitre 3. Du procédural à l'Orienté Objet
Ce chapitre distingue l'approche dite procédurale, axée sur les grandes activités de l'application, de l'approche objet, axée sur les acteurs de la simulation et la manière dont ils interagissent. Nous illustrons cette distinction à l'aide de la simulation d'un petit écosystème.


L'addition des méthodes dans la classe, dès que celles-ci portent sur un des attributs de la classe, transforme ces dernières de simples récipients d'informations en véritables acteurs ; l'objet fait plus qu'il n'est. Il ne se borne pas simplement à stocker son état ; il est surtout le premier responsable des modifications que celui-ci subit. Il sait et il fait, tout à la fois. Q'un second objet, quelconque, désire se renseigner sur l’état du premier ou d'entreprendre de modifier cet état, il devra passer par les méthodes de ce premier objet qui, seules, ont la permission de lire ou transformer cet état. L'objet devra toujours être accompagné de son mode d'emploi, défini dans une structure de donnée à part : son interface.

Transition vers l'objet il est indéniable qu'il existe aujourd'hui deux manière de penser les développements logiciels : la manière dite « procédurale » (C, Pascal, Fortran...) et la manière dite « orienté objet » (Java, C#, C++),aujourd'hui, l'orienté objet prend le pas sur le procédurale. De manière à différencier ces deux approches, nous allons simuler un écosystème dans lequel, comme indiqué dans la figure ci-dessous, évoluent un prédateur (le lion), une proie (l'oiseau) et des ressources, eau et plante, nécessaire à la survie des deux animaux.

Simulation de l'écosystème mise en pratique : Voici les scénarios, la proie se déplace vers l'eau, vers la plante, ou afin de fuir le prédateur; elle agit en fonction du premier de ces objets qu'elle repère. La vision, tant de la proie que du prédateur, est indiquée par une ligne, qui part d'un des coins de l'animal et balaie l'écran. Quand la ligne de vision  traverse un objet, quel qu'il soit, l'objet est considéré comme repéré, la vision ne quitte plus l'objet, et l'animal se dirige vers la cible ou la fuit. Le prédateur se déplace vers l'eau ou poursuit la proie, la aussi en fonction de premier des deux objets perçus. L'énergie selon laquelle les deux animaux se déplacent décroit au fur et à mesure des déplacements, et conditionne leur vitesse de déplacement.
Dès que le prédateur rencontre la proie, il la mange. Dès que le prédateur ou la proie rencontre l'eau, ils se ressourcent (leur énergie augmente) et l'eau diminue de quantité (visuellement la taille de la zone d'eau diminue). Dès que la proie rencontre la plante, elle se ressource (son énergie augmente également) et la plante diminue de quantité (sa taille diminue). Enfin, la plante pousse lentement avec le temps, alors que la zone d'eau, au contraire, s'évapore.

Analyse :
Fonction Principale : Quelles sont les fonctions que tous les objets doivent accomplir ici ?
 - Tout d'abord, la proie et le prédateur doivent se déplacer. On commencera donc à penser et coder les déplacements des animaux, ensemble. Le fait de les traiter ensemble, même s'il s'agit de deux entités différentes, est très important. Il faudra préalablement que chacun des animaux repère une cible. La fonctionnalité  « déplacement » devra faire appel à une nouvelle fonctionnalité, de « repérage », qui elle également, concerne les deux objets. En effet, les deux objets doivent se repérer entre  eux : le prédateur cherche la proie, la proie cherche la plante et à éviter le prédateur, et tous deux cherchent l'eau. Le repérage se fait à l'aide de la vision, un bloc  procédural constitué de deux fonctionnalités semblables que l'on associe à chaque animal et qui n'agira que pendant le repérage.
- Une deuxième grande fonctionnalité est le ressourcement de la proie et du prédateur. Ce ressourcement concerne à nouveau tous les deux objets animaux, pour la proie comme pour le prédateur, il fonctionnera différemment selon la ressource rencontrée. Par exemple, lorsque la proie rencontre la plante, elle la mange et la plante s'en trouve diminuée. Lorsque le prédateur rencontre la proie, il la mange, et la proie, morte, disparaît de l'écran .
- La troisième fonctionnalité est l'évolution dans le temps des ressources, la plante poussant et l'eau s'évaporant.
Le programme principal se trouvera finalement constitué de tous les objets du problème, et ensuite de trois grandes procédures :  « déplacement », « ressourcement », « évolutions des ressources ». La première d'entre elle fait appel à une nouvelle procédure de repérage entre les objets. Cette décomposition fonctionnelle est représentée ci-dessous. 

Conception objet, la pratique orientée objet cherche d'abord à identifier les acteurs du problème et à les transformer en classe, regroupant leurs caractéristiques structurelles et comportementales. Les acteurs ne se limitent pas à exister structurellement, ils se démarquent surtout par le comportement adopté, par ce qu'ils font, pour eux et pour les autres. Ce ne sont plus les grandes fonctions comme en orientée procédurale qui guident la construction modulaire  du logiciel, mais bien les classes/acteurs eux-mêmes. Les acteurs ici sont la proie, le prédateur, l'eau, la plante. Une fois que l'on a établit les attributs de chacun la suite consiste à réaliser une nouvelle analyse fonctionnelle, mais particularisée à chaque acteurs.
Que font, pris individuellement, ces acteurs ? A partant du plus simple d'entre eux : 
- La plante pousse et peut diminuer sa quantité.
- L'eau s'évapore et peut également diminuer sa quantité.
- La proie peut se déplacer, et doit pour cela repérer les autres objets. A cette fin, elle utilisera, comme le prédateur, une nouvelle classe vision,constituée d'une longueur, et à même de repérer quelque chose dans son champs. Mais la proie devra d'interagir avec les autres classes. La proie peut boire l'eau et manger la plante. L'interaction avec les autres classes se produit. 
- Le prédateur, à son tour, se déplacer en fonction des cibles, et peut boire l'eau et manger la proie.
Les liens entre objets sont maintenant représentés comme dans figure ci-dessous.
Dépendance fonctionnelle versus indépendance logicielle, alors que l'exécution d'un programme OO repose sur l'essentiel sur un jeu d'interaction entre classes dépendantes, tout est syntaxiquement mis en oeuvre lors du développement logiciel pour maintenir une grande indépendance entre les classes. Cette indépendance au cours du développement favorise tant la répartition  des tâches entre les programmeurs que la stabilité des codes durant leur maintenance, leur réexploitation dans des contextes différents et leur évolution.
En substance, les dépendances entre classes se pensent au coup et deux à deux, et ne sont pas noyées dans la mise en commun de toutes les classes dans les modules d'activité logicielle. Cela conduit à une conception de la programmation sous forme d'un ensemble de couples client-fournisseur (ou serveur) dans laquelle toute classe sera tour à tour client et fournisseur d'une ou de plusieurs autres. Une conception où les classes se rendent mutuellement des services, ou se délèguent mutuellement des resposanbilités, pointe à l'horizon.Une conception bien plus modulaire que la précédente, car le monde contient plus d'acteurs que de fonctions possibles. Les grandes fonctions génériques sont redéfinies pour chaque acteur.

Il est parfaitement incorrect de clamer haut et fort que les performances en consommation des ressources informatiques (temps calcul et mémoire) des programmes OO sont supérieures en général à celles des programmes procéduraux remplissant les mêmes taches. Tout concourt à faire des programmes OO de grands consommateurs de mémoire et de temps de calcul. Les seuls temps et ressource réellement épargnés sont ceux des programmeurs, tant lors du développement que lors de la maintenance et de l'évolution de leur code. L'OO considère simplement, à juste titre que le temps programmeur est plus précieux et plus onéreux que le temps machine.



La Programmation OO: Chapitre 2. Un objet sans classe

Chapitre 2. Un objet sans classe ... ne possède pas de classe
Ce chapitre a pour but d'introduire la notion de classe : de quoi une classe est-elle faite et quel rôle joue-t-elle, durant le développement du programme, sa compilation, sa structuration finale, et surtout son découpage.

Dans les langages OO, la classe est le modèle à respecter, comme une maison le fait du plan de l'architecte,et la chemise du patron du couturier. La classe se décrit au moyen de trois informations :
- Le nom de la classe
- Les attributs de la classe
- Les méthodes de la classe

Définition d'une méthode de la classe : avec ou sans retour : Une méthode retourne quelque chose si le corps de ses instructions se termine par une expression telle que  « return x  ».Si c'est le cas, son nom  sera précédé du type de ce qu'elle retourne comme suit :
 int maMethode(){
         attribut1 = attribut1 + 1 ;
                ....
          return attribut1;
}
La rencontre du  mot return met fin à l'exécution de la méthode en replaçant celle-ci dans le code qui l'appelle par la valeur de ce retour. La différence entre une méthode qui retourne une valeur et une qui ne retourne rien (void précède alors le nom  de méthode) se marque uniquement dans le contexte d'exécution de la méthode.
En langage procédural ont fait la distinction entre une fonction (déclarée avec un retour) et une procédure (déclarée sans retour et qui se borne à modifier des données du code ). 

Une méthode, comme toute opération informatique (fonction ou procédure), peut recevoir un ensemble d'argument entre les parenthèses,dans l'exemple ci-après l'argument entier  « a ».
 void maMethode( int a ){
         attribut1 = attribut1 + a ;
               ....
}
Identification et surcharge des méthodes par leur signature : La signature de la méthode est ce qui permet de la retrouver dans la mémoire des méthodes. Elle est constituée du nom, de la liste, ainsi que du type des arguments.Toutes modification de cette liste entraîne la création d'une nouvelle méthode,surcharge de la précédente. La nature du return ne fait pas partie de cette signature dans la mesure où deux méthodes ayant le même nom et la même liste d'arguments ne peuvent différer par leur return comme ci-dessous.
class MaClasse1 {
   void maMethode( ){
         attribut1 = attribut1 + 1 ;
               ....
     }
    void maMethode( int a ){
         attribut1 = attribut1 + a ;
               ....
     }
     void maMethode( int a, int b ){
         attribut1 = a + b ;
               ....
     }
     int maMethode( int a, int b ){ /* Il est interdit de définir cette méthode, présentant la même signature, mais un type de retour différent de la précédente */ 
     }
}

La classe est un module fonctionnel , l'existence de la classe nous épargnera  de préciser, pour chaque objet, le nombre et le type de ses attributs,ainsi que la signature et le corps des méthodes qui manipulent ces derniers,économie d'écriture non négligeable et dont l'effet va croissant avec le nombre d'objets issus d'une même classe.En général, tout programme OO manipulera un grand nombre d'objets d'un même classe, ces objets seront stockés dans des ensembles informatiques particuliers, que l'on dénomme des collections.Il s'agira des listes pour les ensembles extensibles, ou des tableaux pour les non extensibles.

Il est considéré comme une très bonne pratique en programmation, de ne jamais créer une variable quellle qu'elle soit sans l'initialiser au préalable et certainement avant toute utilisation.Pour ce qui est des objets, c'est bien parce qu'il s'agit de l'unique information à compléter qu'une méthode particulière portant le même nom que la classe s'y emploiera.On appelle cette méthode singulière le constructeur.
Le constructeur : C'est une méthode particulière, ayant le même nom que la classe,définie sans type de retour.sont rôle est d'initialiser les attributs d'un objet dès sa création.Contrairement aux autres méthodes qui s'exécutent alors qu'un objet est déjà créé et sur celui-ci, il n'est appelé que lors de la construction de l'objet, et une version par défaut est toujours fournie par les langages de programmation. La recommandation, classique en programmation, est d'éviter de se reposer sur le « défaut », et de là toujours prévoir un constructeur pour chacune des classes créées, même s'il se limite à reproduire le comportement par défaut.Le constructeur est souvent une des méthodes les plus surchargées, selon les valeurs d'attributs qui sont connues à la création de l'objet et qui sont passées comme autant d'argument. 

Ainsi un des constructeurs de la classe MaClasse pourrait se définir comme suit : 
MaClasse( int attribut1Init , double attribut3Init ){ // pas de valeur de retour pour le constructeur 
       attribut1 = attribut1Init ; 
       attribut3 = attribut3Init ;
       attribut2 = 1 ; 
}
Cependant dès qu'un constructeur est défini dans la classe,et pour autant qu'il reçoivent un ou plusieurs arguments, il ne sera plus possible de créer un objet en n'y indiquant aucun argument (sauf si le constructeur est explicitement surchargé par un autre qui ne reçoit aucun argument). Comme il est de bonne pratique en informatique de toujours avoir la maîtrise de l'initialisation des objets qu'on utilise, prenez l'habitude, pour éviter toute surprise, de toujours définir un constructeur.
Voyons deux façons différentes de créer un objet et de faire appel à une méthode de cette classe:
Exemple 1 : 
   MaClasse monObjet = new Maclasse( 3 , 5 ) ;/* création de l'objet et assignation de l'adresse de    l'objet comme valeur du référent */ 
   monObjet.methodex(3) ;

Exemple 2 : 
   MaClasse monObjet ; // création du seule référent initialisé à null.
   monObjet.methodex(3) ;
A la fin de la première instruction de l'exemple 2, seul le référent est créé, et typé. Il n'est pas incorrect aux yeux du compilateur d'envoyer un message à même ce référent par l'intermédiaire de la deuxième instruction monObjet.methodex(3) bien que l'objet ne soit pas créé. Bien évidement, cela plantera à l'exécution et produira une exception de type NullPointer,une des erreurs les plus fréquentes en Java et C# (et que le compilateur attentif soit-il ne peut anticiper).
Cela démontre que le compilateur ne se préoccupe jamais de la partie new des instructions de créations d'objet et limite son attention à la déclaration statique.Le reste, la création à proprement parler, ne se déroule que pendant l'exécution. 
La figure ci-dessous illustre les trois étapes de la construction d'objet déclenchées par l'instruction  :
MaClasse monObjet = new Maclasse( 3 , 5 ) ;

Mémoire dynamique, mémoire statique : A l'époque des tous premiers langages de programmation à l'issue de la compilation, il y avait moyen de prévoir de quelle quantité de mémoire vive le programme aurait besoin pour son exécution, la gestion s'effectuait selon le principe dit de « mémoire pile » toujours d'actualité dans la plupart des langages d'aujourd'hui. La gestion pile revient à empiler et dépiler les données à mémoriser pour y placer en respectant un mécanisme de type dernier rentrant premier sortant, en fonction du début et de la fin des blocs d'instructions dans lesquels ces données opèrent. Ce mode de gestion mémoire est également décrit comme « statique ».
Le mot réservé new ,autorise un programme au cours de son exécution, non seulement à allouer de l'espace mémoire pour y placer de nouvelles variables (des objets) , mais également à les disposer n'importe où dans cette mémoire et sans contraindre leur répartition et disparition de leur seule présence dans les blocs d'instructions. Ce mode alternatif de gestion de mémoire est généralement taxé de « dynamique ».

La classe comme garante de son usage. Contrairement aux langages « interprétés » comme Pythons et PHP 5, dans les langages compilés comme C# et Java le compilateur a pour fonction critique de générer du code  « exécutable », et que son utilisateur exige le moins inattendu possible, le compilateur prendra garde de vérifier que rien de ce qui est écrit par le programmeur ne puisse être source d'imprévu et d'erreur.Et c'est la que la classe joue de nouveau un rôle considérable, en permettant au compilateur de se transformer en cerbère,  et de s'assurer que ce qui est demandé aux objets (essentiellement l'exécution de messages) est de l'ordre du possible. La classe est assurée par avance que tout de ce que feront ses objets est conforme à  ce qui est spécifié dans le contrat. Et ce contrat est passé avec le compilateur. On ne peut envoyer sur l'objet un message qui ne soit pas une des méthodes prévues par sa classe. On dit des langages qui permettent cette vérification qu'ils sont fortement typés.
Le langage est fortement typé quand le compilateur vérifie que l'on ne fait avec les objets et les variables du programme que ce qui est autorisé par leur type.Cette vérification a pour effet d'accroître la fiabilité de l'exécution du programme, l'étape de compilation y est essentielle.

Mémoire de la classe, dans une application logicielle particulière quand tous les objets ont une valeur d'attribut commune, il n'est plus nécessaire d'installer cet attribut dans l'espace mémoire alloué à chaque objet, vu que la valeur est commune à tous les objets.Il serait plus naturel, à l'instar des méthodes, de l'installer dans les espaces mémoire dédiés aux classes. On qualifie ce type d'attribut particulier, dont les valeurs sont partagées par tous les objets et deviennent de ce fait plutôt attribut de classe que d'objet, d'attribut statique.On retrouve ces attributs dans la zone de mémoire des méthodes.

Méthode de la classe et des instances, certaines méthodes peuvent également être déclarées statiques,elles se rapportent à la classe plutôt qu'à un objet. Les praticiens de Java ou de C# connaissent tous une célèbre méthode statique,totalement inévitable, la méthode main(). En Java et C# le « main » est une méthode statique, car il n'est, en effet, pas nécessaire de lancer cette méthode à partir d'un objet.
Statique: Les attributs d'une classe dont les valeurs communes à tous les objets, et qui deviennent ainsi directement associés à la classe, ainsi que les méthodes pouvant s'exécuter directement à partir de la classe, seront déclarées comme statique. Ils pourront s'utiliser en l'absence de tout objet. Une méthode statique ne peut utiliser que des attributs statiques, et ne peut appeler en son sein que des méthodes également déclarées  comme statiques.

Liaison naturelle et dynamique des classes. La classe, par le fait qu'elle s'assimile à un petit programme à part entière, constitue un module idéal pour le découpage du logiciel en ses différents fichiers. La liaison sémantique entre classes, rendue possible si la première intègre en son code un appel à la seconde, devrait suffire à relier de façon dynamique, pendant la compilation et l'exécution du code, les fichiers dans lesquels ces classes sont écrites.






La Programmation OO: Chapitre 1. Principe de Base

Chapitre 1. Principe de Base : Quel genre d'objet pour l'informatique ?
Ce chapitre a pour but une introduction aux briques de base de la conception et de la programmation orientée objet (OO). Il s'agit pour l’essentiel des notions d'objet, de classe,  de message et d'héritage.

On  peux souligner cette notion de trio: < entité , attribut , valeur >
Il est possible dans tous les langages informatiques de stocker et de manipuler des objets en mémoire, comme autant d'ensemble de couples attribut/valeur.

Les objets sont structurellement  décrit par un premier ensemble d'attributs de type primitif (tel qu'entier, réel ou caractère) qui permet de déterminer l'espace qu'ils occupent en mémoire.

Le Référent d'un objet,c'est à dire le nom  de l’objet (ex : Object 1,Object 2, .. Object n),contient l'adresse physique de l'objet en memoire,cette adresse peut être codée sur 32 bits,64 bits ou autre en fonction du processeur et du système d'exploitation.Il est dès lors important de souligner que ce référent doit être unique à chaque objet.

Cela dit on peut se poser une  question à savoir si plusieurs référents peuvent pointer sur un même objet  ou si un même objet peut  avoir plusieurs noms ? La réponse est "OUI".
Grâce au mécanisme  puissant et souple de référence informatique ,à savoir l'adressage indirect
C'est la possibilité pour une variable d'être associée à une adresse physique d'un emplacement contenant lui, cette donnée.Il devient même possible de différer le choix de cette adresse pendant l’exécution du programme, tout en gardant la même variable.






On acceptera à ce stade-ci qu'il est utile qu'un objet séjourne en mémoire tant qu'il est possible de le référer.Sans référent un objet est bon pour la casse puisque inaccessible.

L'objet et ses constituants : Il faut séparer physiquement ce que les autres objets doivent savoir d'un objet   donné, afin de solliciter ses services, de ce que ce dernier requiert pour son fonctionnent, a savoir la mise oeuvre de ces même services.Il y a des relations de type composition, où certains se trouvent contenus dans d'autres et ne sont accessibles qu'à partir de ces autres.Leur existence  dépend entièrement de celle des objets qui les contiennent, on parle alors d'objet composite.
Exemple : Le moteur d'une voiture. (si on détruit l'objet voiture on détruit implicitement l'objet moteur). 


D'autres Modes de mise en relation entre objets devront être considérés, qui permettent à un premier de se connecter facilement à un deuxième, mais sans que l'existence de celui-ci ne soit entièrement conditionnée par l'existence du premier.
Exemple : Le  passager d'une voiture. (si on détruit l'objet voiture on ne détruit pas l'objet passager, car l'objet passager ne dépend pas de l’objet voiture).

Les différents états d'un objet : Les objets changent donc d'état, continûment, mais tout en préservant leur identité, en restant ces mêmes objets qu'ils ont toujours été. Les objets sont dynamiques, la valeur de leurs attributs change dans le temps soit par des mécanismes qui leur sont propre,soit en raison d'une interaction avec un autre objet.
Le cycle de vie d'un objet lors de l'exécution d'un programme orienté objet, se limite à une succession de changements d'états, jusqu'à sa disparition de la mémoire centrale.

Dans la mémoire dite centrale RAM ou vive d'un ordinateur, ne se trouve toujours installés que deux types d'informations, les données (ou valeurs des attributs) stockées sur une partie leur est propre et les instructions sur une autre partie également propre aux instructions  qui utilisent et modifient les données rien d'autre, le tout lié dans ce que l'on appelle Classe.

La Classe : C'est la structure de données en POO qui unit en son sein tous les attributs de l'objet et toutes opérations, opérations que l'on désigne couramment par méthode.Les méthodes s'occupent de la partie active de la "classe" 
La classe est ce contrat qui lie à vie les attributs de l'objet et les méthodes qui utilisent ces attributs.Tout devra impérativement respecter ce qui est dit par classe,sinon gare au compilateur.
S'agissant d'une variable manipulée, on parle de l'objet comme d'une instance de sa classe et de la classe comme du type de cet objet.Chacun des attributs de l'objet seront uniquement ceux prévus dans leur classe. D'où l'intérêt, bien sûr de garder la définition de la classe séparée mais partagée par toutes les instances de celles-ci.Non seulement c'est la classe qui détermine les attributs (leur type) sur lesquels les méthodes pourront opérer mais, seules les méthodes déclarées dans la classe peuvent de facto manipuler les attributs les objets typés par cette classe comme suit : 
class MaClasse1 
       int attribut1;
       int attribut2;
            .....
       int attributn;
       méthode1() {
             attribut1 = attribut2 + 1 ;
             .....
       }
}
Lier la méthode à  l'objet : On lie une méthode f ( x ) à l'objet  "a" , sur lequel elle doit s'appliquer, au moyen d'une instruction comme : a . f ( x ). Par cette écriture, la méthode f ( x ) saura comment accéder aux seuls attributs de l'objet, ici les attributs de l'objet "a" qu'elle peut manipuler, et dont l'adresse est en effet renseignée par "a".
Les interactions entre objets : Les interactions entre objets se font grâce aux méthodes  qui par ailleurs sont prévus dans certains cas pour recevoir des arguments d'un quelconque type,cela afin de leur permettre d'affiner leur effet en fonction de la valeur de l'argument.
Méthode : C'est un regroupement d’instructions qui ne s'exécute toujours que sur un objet précis.
Envoi de message : Le seule mode de communication entre deux objets revient à la possibilité pour le premier de déclencher une méthode sur le second, méthode déclarée et définie dans la classe de celui-ci. On appellera ce mécanisme de communication "envoi de message" du premier objet vers le second.

Les objets entre eux sont soumis à une hiérarchie, on parle alors de "Héritage et taxonomie".C'est une pratique de l'orienté objet que d'organiser des classes entre elles de manière hiérarchique ou taxonomique, des plus générales aux plus spécifiques. On parle de mécanisme "d'héritage" entre classes. Un objet, instance d'une classe, sera à la fois instance de cette classe mais également de toutes celles qui la généralisent et dont elle hérite.Tout autre objet ayant besoin de ses services choisira de le traiter selon le niveau hiérarchique le plus approprié.
Héritage : Le rôle premier de l'héritage est de favoriser une économie de représentation et de traitement. La factorisation de ce qui est commun à plusieurs sous-classes dans une même superclasse offre des avantages capitaux.Vous pouvez omettre d'écrire dans la définition de toutes les sous-classes ce qu'elles héritent des superclasse. Il est de bon sens que, moins on écrit d'instructions, plus fiable et plus facile à maintenir sera le code.
Par l'héritage et généralisation ainsi faite nous retrouvons la même dénomination pour des activités partagées par un ensemble d'objets, mais dont l'exécution se particularise en fonction de la vrai nature de ces objets. Cela permet à un premier objet, interagissant avec cet ensemble d'objets, dont il sait qu'ils sont à même d'exécuter ce message, de le leur adresser sans se préoccuper de cette nature intime. Une grande économie de conception et un gage de stabilité sont permis par ce mécanisme : Polymorphisme.
Polymorphisme : Conséquence directe de l'héritage,permet à un même message, dont l'existence est prévue dans une superclasse, de s'exécuter différemment, selon que l'objet qui le reçoit est d'une sous-classe ou d'une autre.Cela permet à l'objet responsable de l'envoie du message de ne pas avoir à se préoccuper dans son code de la nature ultime de l'objet qui le reçoit et donc de la façon dont il l'exécutera.


Conclusion : Cette structuration cognitive reflète, en partie, la réalité qui nous entoure, mais surtout notre manière de la percevoir et de la communiquer, tout en se soumettant à des principes universaux d'économie, de simplicité et de stabilité.