Une remarque pertinente ? Une critique impertinente ? Un lynchage en règle ? Une invitation sous les tropiques ? Ecrivez-moi ! |
|
Conçu et enseigné tel qu'en lui même, avec pertes, fracas et
humour de qualité supérieure par Christophe Darmangeat dans le M2 PISE du Master MECI (Université Paris 7) |
|
|
Partie 1
VB.NET, un langage objet
1. C'est quoi, un langage objet ?
Vous le savez sans doute déjà : VB.NET est un langage objet. Ce n'est
pas le seul : C# (prononcez "cécharpe"), C++ ou Java sont eux aussi des
langages objets. Ce type de langage, apparu dans les années 1990,
s'oppose en particulier aux langages de la génération précédente, qui étaient
dits "procéduraux" (comme le Cobol, le Fortran, le Pascal, le C et bien
d'autres, on ne va pas tous les citer, on n'a pas que cela à faire non
plus).
La première chose à dire des langages objet, c'est qu'ils permettent de
faire tout, absolument tout, ce qu'on pouvait faire avec un langage
procédural.
Donc, et c'est la bonne nouvelle du jour, rien de ce que vous avez
appris n'est perdu ! Les langages objet, comme leurs ancêtres les
langages procéduraux, manipulent des variables, des tableaux et des
structures, et organisent des instructions d'affectation,
d'entrée-sortie, de tests ou de boucles dans des procédures et des
fonctions. Donc, à la limite, on peut (presque) programmer en langage
objet exactement comme on programmait en langage procédural. Mais évidemment, ce serait bien dommage,
car on passerait alors à côté de ces petits riens que les langages objet
possèdent en plus, petits riens qui vont nous changer la vie...
Remarque sournoise :
S'il y a quelque chose que vous ne comprenez pas dans le paragraphe qui précède, c'est vraisemblablement que vous avez doublement brûlé les étapes. D'une part, en voulant apprendre VB.NET sans avoir appris l'algorithmique. D'autre part, en n'ayant pas lu assez attentivement les Préambules nécessaires (ce qui n'est pas bien) ou en les ayant lu, et en choisissant de les ignorer (ce qui est encore pire). Dans les deux cas, vous n'échapperez pas à un retour par la case départ, et vous ne touchez pas 20 000 F.
Reprenons. Les langages objet, tout en intégrant l'ensemble des
capacités des langages procéduraux, possèdent deux aptitudes
supplémentaires, aptitudes liées mais distinctes. Ces langages peuvent
en effet :
On verra plus tard que par contamination, les
langages objet ont tendance à tout assimiler à des objets, même des
choses qui n'en sont pas spécialement, comme les bonnes vieilles
variables de notre enfance. Mais n'anticipons pas, et examinons tout
d'abord les deux points ci-dessus plus en détail.
1.1 Qu'est-ce qu'un objet ? Parlons comme les gens normaux Dans la vie de tous les jours, nous sommes entourés d'objets.
Certains très simples, comme un peigne, un bouton de culotte ou une
matraque de CRS. D'autres très complexes comme une automobile, un
ordinateur ou une
navette spatiale. Pour faire l'analogie avec les objets des langages
objet, mieux vaut penser à un objet un peu compliqué qu'à un objet trop
simple. Et pour cette analogie, rien ne nous oblige à penser à un objet
inanimé. Des plantes, des animaux ou des êtres humains peuvent tout à
fait être assimilés aux objets que manipulent les langages.
Dans les objets, il y a deux sortes de choses qui intéressent les
informaticiens.
Tous les objets possédant les mêmes caractéristiques et avec lesquels
on peut faire les même choses forment un groupe qu'on appelle en
informatique une classe.
Par exemple, tous les chiens, et c'est à cela qu'on les reconnaît, ont une couleur de
pelage, une taille, un poids, etc. Ils peuvent tous aboyer, courir,
sauter, etc. Même si chacune de ces aptitudes est différente d'un
chien à l'autre, et même si le chihuahua de ma cousine est assez
différent du rottweiler de mon voisin, ces deux bestioles ont en commun
de posséder certaines caractéristiques et de pouvoir effectuer certaines
actions. Ils font donc partie d'une classe unique que j'appelle « les
chiens », même si d'un chien à l'autre, et ma cousine en sait quelque
chose lorsqu'elle croise mon voisin, la taille et le poids (entre
autres) ne sont pas les mêmes.
En prenant le problème à l'envers : si je définis une classe par
l'ensemble de ses caractéristiques et de ses actions, je peux, à partir
de cette classe, fabriquer tout plein de toutous différents les uns des
autres, mais qui auront en commun d'être tous des chiens (donc,
répétons-le lourdement, des êtres qui partageront les mêmes caractéristiques et qui
seront capables des mêmes actions).
Eh bien, les langages objet, ce sont des langages qui permettent, en
plus des traditionnels variables, tableaux et structures, de gérer et de
manipuler des objets (donc des classes). C'est-à-dire que ces langages
permettent notamment :
Tout ce que nous avons vu là peut être traduit dans des termes
techniques propres aux informaticiens.
1.2 Qu'est-ce qu'un objet ? Parlons comme les informaticiens Nous savons que tout programme informatique a pour but de manipuler
des informations. Et nous savons que ces informations relèvent toujours, au
bout du compte, de l'un des trois grands types simples : numériques, caractères
(alphanumériques), ou booléens.
Lorsque nous disons qu'un objet (ou une classe) possède des
caractéristiques comme la taille, le poids, la couleur, etc., nous
disons en fait qu'un objet (ou une classe) regroupe un certain nombre de
variables : une variable numérique pour stocker le poids, une autre
variable numérique pour stocker la taille, une variable caractère pour stocker la
couleur, etc.
Donc, première chose, un objet regroupe un ensemble de variables qui
peuvent être de différents types. Et dans ce cas, on ne parlera pas des
"variables" d'un objet, ni des ses "caractéristiques", mais de ses
propriétés (ou encore, de ses attributs).
Définition :
Une propriété d'un objet est une des variables (typée) associées à cet objet.
Théorème :
Par conséquent, toute instruction légitime avec une variable est légitime avec une propriété d'un objet. Et lycée de Versailles, tout ce qui n'avait pas de sens avec une variable n'a pas non plus de sens avec une propriété d'un objet. Mais jusqu'à maintenant, allez-vous dire, nous n'avons fait que faire de
la mousse avec du vocabulaire nouveau autour d'une notion que nous
connaissons déjà comme notre poche. Parce qu'enfin, quoi, un bidule
constitué de différentes variables de différents types, on n'a pas
attendu les objets pour en avoir. Tous les langages procéduraux
connaissent cela, mis à part qu'on ne parle pas de classe mais de
structure, qu'on ne parle pas d'objets, mais de variables structurées,
et qu'on ne parle pas de propriétés, mais de champs. Mais pour le reste,
c'est tutti quanti et du pareil au même.
Les esprits chagrins qui feraient cette remarque auraient parfaitement
raison... si les objets n'étaient effectivement qu'un ensemble de caractéristiques (de propriétés).
Mais les objets ne sont pas que cela : ils
incluent également, comme on l'a vu, des actions possibles. Autrement
dit, un objet (une classe) est un assemblage d'informations (les
propriétés) mais aussi d'instructions (les actions, que l'on appelle les
méthodes). C'est cette présence des méthodes qui différencie une
classe d'une simple structure, et un objet d'une simple variable
structurée. On peut donc dire qu'un objet, c'est une structure plus des procédures.
Définition :
Une méthode est une procédure (donc un ensemble d'instructions) associée à un objet (et à sa classe). Notons dès à présent que les classes (donc, les objets)
peuvent aussi être associés à ce que l'on appelle des événements,
événements qui joueront un rôle essentiel dans le déroulement de notre
application.
Nous mettons donc dès à présent le doigt sur la différence profonde qui existe entre un langage procédural
traditionnel et un langage objet : il s'agit de la manière dont sont articulées les informations et les traitements permettan de les modifier.
2. La syntaxe objet 2.1 Généralités
Lorsque nous fabriquions (et nous en fabriquerons encore) une variable,
nous utilisions un « moule » à variable, qui s'appelle un type. Pour créer
une nouvelle variable, il fallait lui donner un nom, par lequel on
pourrait la désigner tout au long du programme, et préciser le type
utilisé pour la fabrication de cette variable. D'où la syntaxe du genre :
Dim Toto As Integer
Eh bien, en ce qui concerne les objets, le principe est exactement le
même, hormis qu'on ne les fabrique pas avec un type, mais avec une
classe. Si nous disposons par exemple d'une classe Chien, nous allons
pouvoir créer autant de chiens individuels que nous voulons. Voilà par exemple un
nouveau compagnon :
Dim Rantanplan As New Chien
On remarque la présence du mot clé New, propre aux déclarations
d'objets, et qui différencie celles-ci des déclarations de variables.
Dans le jargon du langage objet, cette instruction New s'appelle un
constructeur.
Vocabulaire savant :
Créer un objet d'après une classe s'appelle instancier la classe. Un objet peut aussi être appelé une instance, ou une occurrence, de la classe. Notre classe Chien a forcément été créée avec un certain nombre de
propriétés et de méthodes. Pour chaque objet instancié selon cette classe, nous pouvons accéder à ces propriétés et à
ces méthodes par la syntaxe suivante, universelle :
Nom-d'objet.Nom-de-propriété
Et également :
Nom-d'objet.Nom-de-Méthode
Remarque fondamentale :
Dans un langage objet, on ne peut trouver que les deux syntaxes ci-dessus. Sauf dans des cas exceptionnels, il est impossible de désigner un objet sans le faire suivre d'une propriété ou d'une méthode. C'est une faute de syntaxe. De même, on ne trouvera jamais une propriété ou une méthode seules, non précédées de l'objet auxquelles elles se réfèrent. 2.2 Propriétés Admettons pour les besoins de la cause que notre classe
Chien possède
entre autres propriétés :
Alors, je le rappelle, les règles d'utilisation de ces propriétés
sont très exactement les mêmes que celles des variables. Sachant que le
signe d'affectation, en Visual Basic, est le signe d'égalité, je peux
donc écrire :
Rantanplan.Poids = 14
Et je viens de fixer le poids de mon toutou à 14 kg. Pour le faire
grossir de 5 kg, rien de plus simple :
Rantanplan.Poids = Rantanplan.Poids + 5
...et le tour est joué. Si je veux torturer la pauvre bête, je peux
aussi la rendre aussi lourde que haute, en écrivant :
Rantanplan.Poids = Rantanplan.Taille
L'utilisation de propriétés non numériques ne pose pas davantage de
problèmes :
Rantanplan.Couleur = "Beige"
Rantanplan.Vacciné = True
2.3 Méthodes
Je le rappelle, si les propriétés sont en réalité des variables (et, pour être, encore plus précis,
des champs de structures), les
méthodes sont quant à elles des procédures. Utiliser convenablement une
méthode suppose donc de respecter la manière dont la procédure a été écrite.
En particulier, comme à chaque fois en pareil cas, il va falloir respecter le nombre et le type des paramètres dont la méthode (la
procédure) a besoin pour s'exécuter. Ainsi, certaines méthodes
peuvent-elles être utilisées sans passer de paramètres. D'autres en
exigeront un, d'autres deux, etc.
Dans tous les cas, cependant, une méthode étant un appel de procédure, elle représente donc en elle-même une instruction à part entière.
Il serait donc parfaitement
absurde d'affecter une méthode comme on affecte une propriété. Les appels aux méthodes pouront donc donner lieu à des lignes du genre :
Rantanplan.Aboyer
...si la méthode Aboyer s'emploie sans arguments,
Rantanplan.Courir(15)
...si la méthode Courir nécessite un argument numérique, celui fixant la vitesse de course,
Rantanplan.DonnerlaPapatte("gauche")
...si la méthode DonnerlaPapatte réclame un argument de type caractère, etc.
Si vous avez compris cela, vous avez compris
45 % de ce cours. Très exactement, au millipoil près.
3. La programmation événementielle
Nous ne sommes pas au bout de nos peines (ni au bout de nos joies). Toute
cette sombre histoire d'objets cache une autre drôle de plaisanterie,
qui va radicalement transformer la manière dont les procédures d'un
programme vont être exécutées, et du coup, la manière dont les
programmeurs vont devoir concevoir leurs applications.
C'est le deuxième aspect dont je parlais au début de
ce chapitre,
aspect qui est lié à la programmation objet, mais qui ne se confond
pas tout à fait avec elle. De quoi s'agit-il ?
Rappelons-nous comment
notre code était organisé dans un langage procédural traditionnel. Plutôt qu'une immense procédure fait-tout,
comportant des redites de code, nos applications, dès lors qu'elles
devenaient un peu joufflues, étaient organisées en modules séparés :
sous-procédures et fonctions (lesquelles, je le rappelle, ne sont jamais
qu'un cas particulier de sous-procédures).
Parmi ces diverses procédures, il s'en trouvait une
qui jouait un rôle particulier : la
procédure principale (appelée Main dans la plupart des langages). C'est
elle qui était exécutée lors du lancement de l'application. Et c'est
elle qui tout au long du programme, telle un chef d'orchestre,
déclenchait les autres procédures et les autres fonctions.
Le point important dans cette affaire, c'est qu'une fois
l'application lancée, une procédure donnée ne pouvait s'exécuter que si
une ligne de code, quelque part, en commandait le déclenchement.
L'utilisateur n'avait aucune espèce de moyen d'influencer directement
l'ordre dans lequel les procédures allaient être exécutées.
Tout ceci va être remis en question avec les langages objet. Non
qu'on ne puisse plus créer encore des procédures et des fonctions, et
appeler les unes via les autres par des instructions adéquates ; je le
rappelle, il n'y a rien qu'on pouvait faire avec un langage procédural
qu'on ne puisse faire avec un langage objet. Mais avec un langage objet,
on va pouvoir faire certaines choses véritablement inédites. En
l'occurrence, la grande nouveauté, c'est qu'on va pouvoir organiser le
déclenchement automatique de certaines procédures en réponse à certaines
actions de l'utilisateur sur certains objets. Et ces actions, ce
sont les fameux événements dont je parlais tout à l'heure.
Pour comprendre cela, le plus simple est de penser que certains
objets ont une caractéristique particulière : ils se voient à l'écran.
Un système d'exploitation tel que Windows est truffé de ce genre d'objets !
Les boutons, les menus, les fenêtres, les cases à cocher, tout cela
constitue une armada d'objets visibles, et surtout, capables de réagir à
diverses sollicitations de l'utilisateur via le clavier ou la souris.
Les programmeurs qui ont écrit Windows ont donc prévu, et écrit, des
myriades de morceaux de code (des procédures) qui se déclenchent à
chaque fois que l'utilisateur accomplit telle action sur tel type
d'objet, par exemple, le clic sur un bouton, le duble-clic sur un raccourci, etc.
Donc, je le répète, concevoir une application événementielle,
c'est concevoir des procédures qui se
déclencheront automatiquement à chaque fois que l'utilisateur
effectuera telle action sur tel objet qu'on aura mis à sa disposition.
Remarque
profonde :
Dans les phrases qui précèdent, les mots « à chaque fois que » sont essentiels. Il faut impérativement les avoir en tête lorsqu'on écrit une application objet. Faute de quoi on mélange tout, et en particulier, on se met à écrire des boucles là où il n'y a qu'une simple procédure événementielle.
Définition :
Une action sur un objet capable de déclencher une procédure s'appelle un événement. Voilà pourquoi ce type de programmation porte le nom
de programmation événementielle. Par ailleurs,
je rappelle que les événements qu'un objet donné est capable de
gérer ont été définis dans la classe qui a servi à créer l'objet.
Remarque importante :
Tous les objets capables de gérer un événement ne sont pas forcément des objets visibles à l'écran. Dans le même ordre d'idées, tous les événements ne correspondent pas forcément à des actions de l'utilisateur via le clavier ou la souris. Mais pour commencer, on peut très bien s'accommoder de ces approximations. 3.1 Le diagramme T.O.E. Lors de la conception d'un programme objet, une des premières tâches
du développeur va donc être de concevoir l'interface utilisateur.
C'est-à-dire de prévoir quels objets vont être mis à sa disposition à l'écran, quelles seront les actions qu'il pourra effectuer
sur ces objets (c'est-à-dire les événements qu'il pourra déclencher) et de prévoir les tâches que le
programme devra accomplir lors de ces événements.
Remarque incidente :
Pour le moment, nous nous contenterons de considérer que nos applications emploient uniquement l'arsenal des objets utilisés par Windows. Ces objets (plus exactement, ces classes) seront donc tout prêts à l'emploi. Leurs propriétés, leurs méthodes et les événements qu'ils sont capables de gérer ont été définis par Windows, c'est-à-dire par Visual Basic (qui nous sert en quelque sorte d'intermédiaire vis-à-vis de Windows, qui parle un langage trop abscons pour nous). En réalité, dans un programme Visual Basic, on peut utiliser des tas d'autres objets (classes) et on peut même en fabriquer soi-même. Nous verrons cela... plus tard. Pour le moment, on se contentera de la trousse à outils que Visual Basic met à notre disposition, ce qui suffira déjà à nous procurer de longues heures de bonheur. Ainsi, nous pouvons prévoir qu'il faudra que la fenêtre de notre
application se présente comme ceci ou comme cela, qu'il devra y avoir
ici un bouton, là des boutons radios, ici une zone de liste, etc. Et
il faut également prévoir qu'un clic sur tel bouton déclenchera tel ou
tel calcul, qu'un choix dans telle liste devra mettre à jour telle ou
telle zone, etc.
Le document synthétique, sous forme de tableau, qui reprend toutes
ces informations, s'appelle un diagramme T.O.E., pour Tâche, Objet,
Événement. C'est un document préalable indispensable à la
programmation d'une application événementielle. Il comporte trois colonnes.
Dans la première, on dresse la liste exhaustive des tâches que doit
accomplir l'application. Dans la seconde, en regard de chaque tâche à accomplir,
on porte, le cas échéant, le nom de l'objet qui en sera chargé. Et dans la troisième,
en regard de chaque objet, on
écrit le cas échéant, mais oui, l'événement
correspondant. Vous l'aviez deviné ? Décidément vous êtes trop forts.
Remarque importante :
Rien, absolument rien, n'impose qu'un objet soit associé à un événement et à un seul. Certains objets peuvent fort bien n'être associés à aucun événement. De même, d'autres objets peuvent très bien gérer plusieurs événements différents, qui correspondront donc à autant de procédures différentes. Commençons par le commencement. Un évènement, en Visual Basic, est formé de la réunion, séparée par un point, des deux éléments suivants :
Nom-d'objet.Nom-d'action
Par exemple, l'événement « l'utilisateur clique sur le bouton du nom de BoutonOK » correspond à :
BoutonOK.Click
Bien sûr, a priori, le nom des évènements ne s'invente pas. Lorsqu'on utilise des classes toutes prêtes (ce que nous ferons durant 99% de ce cours),
on repère dans l'aide du langage quelles actions peuvent être associées à quelles classes, et donc aux objets instanciés d'après ces classes. Par exemple, dans
Windows, la classe des boutons ne gère pas l'action « double clic ». Essayez, dans n'importe quel logiciel sous Windows, de double-cliquer sur un bouton, et vous verrez que c'est
à peu près aussi facile que d'éternuer sans fermer les yeux. Donc, si nous employons dans un programme un objet de classe bouton, il nous sera impossible de lui associer une
action double-clic pour gérer l'événement correspondant. Consolez-vous néanmoins, il y a largement, très largement, de quoi faire avec les classes et les actions existantes,
et nous serons très loin de pouvoir en épuiser les possibilités !
Passons maintennt au deuxième étage de la fusée. Comment la machine établit-elle la liaison entre une procédure et l'événement
qui la déclenche ? C'est extrêmement simple : cette liaison figure en toutes
lettres dans l'en-tête de la procédure, via le mot-clé
Handles (que
l'on peut traduire par "gère"), suivi de l'évènement concerné. Ainsi, une procédure
non événementielle, toute bête, toute simple, nommée Calcul, aura la tête suivante :
Private Sub Calcul()
... instructions ... End Sub Pour que cette procédure s'exécute à chaque fois que l'on clique
sur le bouton nommé Résultat, il suffira qu'elle se présente ainsi :
Private Sub Calcul() Handles Résultat.Click
... instructions ... End Sub
Remarque capitale :
La seule chose qui compte dans la liaison évènement / procédure, c'est... l'évènement (qui figure après le mot-clé Handles). Le nom de la procédure (ce qui suit Private Sub), lui, ne joue aucun rôle. On peut le modifier à loisir, cela ne change strictement rien. Comprendre ceci est d'autant plus important que VB, dans sa bonté naturelle, a tendance à donner aux procédures un titre sur le modèle « NomObjet_NomAction » (par exemple, BoutonOK_Click). On a tôt fait de prendre le leurre pour la proie, et de se mélanger complètement les crayons entre ce qui a une importance vitale (l'évènement qui suit Handles) et ce qui n'en a aucune (le nom de la procédure).
Si d'aventure, une même procédure doit être déclenchée par plusieurs événements différents,
ce n'est pas du tout un souci. Il suffit de séparer tous les événements
concernés par des virgules après le mot clé Handles. Si, par exemple la
remise à zéro doit être effectuée en cas de clic sur le bouton Résultat,
mais aussi de clic sur le bouton Annulation, on aura :
Private Sub RemiseAZero() Handles Résultat.Click, Annulation.Click
... instructions ... End Sub
Et voilà le travail.
En réalité, il y a juste une petite subtilité
supplémentaire. C'est que lorsqu'un événement déclenche une procédure,
Visual Basic prévoit automatiquement un passage de paramètres depuis
l'événement jusqu'à la procédure, passage de paramètres sans lequel on
serait parfois bien embêté.
La syntaxe complète d'une procédure événementielle sera donc
typiquement :
Private Sub RemiseAZero(ici des paramètres) Handles Résultat.Click
... instructions ... End Sub On verra dans quelques temps quels sont ces paramètres et à quoi ils peuvent servir.
En attendant, si vous avez compris le mécanisme des procédures événementielles, alors vous avez alors pigé 45 %
supplémentaires du cours. Donc, avec les 45 % précédents (ceux des classes, des objets, des propriétés et des méthodes),
on en est à 90 %. Tout le reste, c'est de la petite bière. Puisque je vous le dis.
|