Cours eiffel et bioinformatique, tutoriel & guide de travaux pratiques en pdf.
Plusieurs atomes…
Les atomes étant reliés par des liaisons chimiques, créons une classe BOND.
Et une liaison, une !
La classe BOND contient deux atomes qui seront caractéristiques de notre .
Ouvrez un fichier bond.e (dans le même dossier que atom.e ) et saisissez les lignes suivantes:
class BOND
creation
→ make
feature
EBO: Eiffel et BioinfOrmatique 2.4
→ with(atom1, atom2 : ATOM) is
→ → do
→ → → first_atom := atom1
→ → → second_atom := atom2
→ → → io.put_string(« I’m a new bond composed of :%N »)
→ → → io.put_string(atom1.out + « %N »)
→ → → io.put_string(atom2.out + « %N »)
→ → end
→ first_atom : ATOM
→ second_atom : ATOM
end end of class BOND
Pour utiliser la classe BOND, il nous faut un troisième fichier. Ouvrez un nouveau fichier nommé « test.e » (toujours dans la même directory que atom.e et bond.e ) et tapez les lignes suivantes:
class TEST
creation
→ make
feature
→ make is
→ → local
→ → → atom1, atom2 : ATOM
→ → → a_bond : BOND
→ → do
→ → → create atom1.make
→ → → create atom2.make
→ → → create a_bond.with(atom1, atom2)
→ → end
end end of class TEST
La classe BOND contient deux atomes nommés first_atom et second_atom. On appelle ces deux variables, des attributs de la classe BOND. Le constructeur de la classe BOND est une routine nommé with qui « attend » deux arguments de type ATOM. n objet de la classe ATOM et au moment de sa création (dans le constructeur make, on crée avec le mot clé create l’objet first_atom avec le constructeur de ATOM qui se nomme make.
Il faut lancer la compilation en tapant Ctrl+F7, la ligne suivante doit s’afficher:
compile test.e o bond_test clean
Puis exécuter le programme avec F5:
./bond_test
Si tout est correct, la ligne suivante s’affiche:
I’m a new bond composed of :
ATOM#0x9eee040[]
ATOM#0x9eee088[]
Les chiffres hexadécimaux peuvent varier et indiquent simplement que les objets de classe ATOM existent bien quelque part en mémoire.
Un peu de vocabulaire…
Pour pouvoir utiliser first_atom, il faut indiquer au compilateur à quel type d’objet correspond cette variable (appelé aussi attribut); cela constitue la déclaration. On déclare, ici, un attribut nommé first_atom comme étant un objet de classe ATOM. first_atom est aussi appelé une variable d’instance. La déclaration doit se faire en respectant la syntaxe suivante:
nom_attribut : <Nom_de_la_classe>
Des attributs et des méthodes
On modifie….
Un atome est défini par sa position 3D exprimée par ses coordonnées atomiques (x,y,z). On va donc ajouter trois nouvelles caractéristiques (feature en anglais) à la classe ATOM.
Les attributs de ATOM
La classe ATOM aura les caractéristiques suivantes:
✔ x
✔ y
✔ z
On appelle ces caractéristiques, des attributs. Comme en Eiffel, tout est objet, on doit indiquer à
quelle classe appartiennent ces attributs: x, y, z sont des nombres « à virgule » (plus
mathématiquement parlant des nombres réels); on les définit comme des objets de classe REAL.
Modifions la classe ATOM de la manière suivante:
class ATOM
creation
→ make
feature
→ make is
→ → do
→ → → io.put_string(« I’m a new atom with coordinates: »)
→ → end
→ x : REAL
→ y : REAL
→ z : REAL
end end of class ATOM
Trois nouvelles lignes apparaissent dans la classe ATOM:
x : REAL
y : REAL
z : REAL
Ces trois lignes correspondent à la déclaration ainsi que nous l’avons vu pour first_atom.
Les divers objets en interaction dans la classe TEST sont présentés dans le schéma cidessous:
Figure xxx: Contenu de la classe TEST. Les objets sont représentés ici par des boîtes qui contiennent des attributs.
Sauvez la modification (Ctrl+S); puis dans test.e, complétez le fichier avec les lignes suivantes: ….
class TEST
creation
→ make
feature
→ make is
→ → local
→ → → atom1, atom2 : ATOM
→ → → a_bond : BOND
→ → do
→ → → create atom1.make
→ → → create atom2.make
→ → → atom1.x := 10.0
→ → → create a_bond.with(atom1, atom2)
→ → end
end end of class TEST
Compilez test.e (Ctrl + F7) … ☹ malheureusement, le compilateur indique une erreur au niveau de la nouvelle ligne « atom1.x := 10.0 ». En effet, il est impossible de modifier directement la valeur d’un attribut d’un objet en Eiffel, il faut passer par des routines nommées « accesseurs » qui sont des sortes de sas permettant de faire transiter des valeurs de/vers les attributs d’un objet. Pour pouvoir accéder aux attributs d’un objet, il faut pouvoir « ouvrir » la boîte pour en modifier (lire ou écrire) le contenu.
Accéder aux attributs
Dans atom.e, on ajoute ces deux « accesseurs » (pour d’une part, lire l’attribut et d’autre part écrire dans l’attribut) qu’on appelle get_x et set_x.
class ATOM
creation
→ make
feature
→ make is
→ → do
→ → → io.put_string(« I’m a new atom with coordinates: »)
→ → end
→ x : REAL
→ y : REAL
→ z : REAL
feature Access
→ set_x(value : REAL) is
→ → do
→ → → x := value
→ → end
→ get_x : REAL is
→ → do
→ → → Result := x
→ → end
end end of class ATOM
Par habitude, les noms des accesseurs sont souvent composés des préfixes « set_ » ou « get_ » + nom de l’attribut. L’accesseur « set_ » permet d’écrire une valeur dans l’attribut de l’objet et « get_ » de lire l’attribut.
L’accesseur set_x est aussi une routine comme le constructeur make et on retrouve d’ailleurs la
même syntaxe constituée des mots clés is do … end. Toutefois, en plus on trouve entre parenthèses une liste du (des) argument(s) de la routine qui est constituée de la déclaration des variables de la routine. On peut compléter notre syntaxe d’une routine:
nom_de_la_routine(arg1 : MY_CLASS; arg2, arg3, arg4 : YOUR_CLASS) is
→ → → On peut ajouter un commentaire
→ → → sur plusieurs lignes
→ → → si on veut
→ → do
→ → end
Remarque 1: quand la routine n’a pas d’arguments, on ne met pas de parenthèses. Par exemple, make n’a pas d’arguments, il est simplement défini comme make is
Remarque 2: quand la routine a plusieurs arguments, ils sont séparés par des points virgules « ; » .
Par exemple, (arg1 : MY_CLASS; arg2 : YOUR_CLASS; arg3 : OUR_CLASS)
Remarque 3: quand la routine a plusieurs arguments et qu’ils appartiennent à la même classe, ils sont séparés par des virgules « , » puis la liste est terminée par « : » NOM_DE_CLASSE. Par exemple, (arg1, arg2, arg3 : MY_CLASS; arg4 : OUR_CLASS).
Ici, il existe un seul argument nommé value de classe REAL.
→ set_x(value : REAL) is
→ → do
→ → → x := value
→ → end
Ensuite, le bloc de code contient une seule ligne qui indique que la valeur contenue dans la variable value sera affecté à la variable x. Le signe « := » est le symbole d’affectation en Eiffel et permet d’initialiser ou de modifier le contenu de la variable x.
En clair, cela signifie que pour fonctionner correctement set_x attend un nombre réel qu’il placera ensuite dans la variable x.
L’accesseur get_x est aussi une routine qui ne possède aucun argument (il n’y a pas de parenthèses juste après son nom). Par contre, cette routine permet de lire la valeur de x; elle doit donc retourner une valeur de classe REAL, c’est pourquoi on ajoute à la déclaration « : » REAL. On appelle ces routines, des fonctions.
nom_de_la_fonction(a : MY_CLASS; b, c, d : YOUR_CLASS) : OUR_CLASS is
→ → → On peut ajouter un commentaire
→ → → sur plusieurs lignes
→ → → si on veut
→ → do
→ → end
Remarque: En fait, il s’agit de la même syntaxe que la déclaration d’une variable. Il n’y a pas de différence entre une variable et une routine retournant une valeur (hormis le mot clé is terminal).
A l’intérieur du bloc délimité par do et end, il faut indiquer que le résultat doit être retournée par la fonction: c’est le rôle de la variable locale nommée Result. Elle n’a pas besoin d’être explicitement déclarée, car elle possède le même type (classe) que celui de la fonction.
Modifiez bond.e et ajoutez les lignes suivantes après la création de first_atom
first_atom.set_x(10.5)
io.put_real(first_atom.get_x)
io.put_new_line
Compilez (Ctrl+ F7) et exécutez (F5), il s’affiche:
I’m a new atom with coordinates: 10.0
Exercice 1: Complétez cette classe pour implanter les accesseurs de y et z.
Exercice 2: Ajoutez à la classe ATOM, une routine set_coordinates(xx, yy, zz : REAL) qui affectent les valeurs de xx, yy, et zz à x, y et z, respectivement. Modifiez BOND pour tester votre nouvelle routine.
On ajoute ….une routine
Modifions la classe ATOM de la manière suivante:
class ATOM
creation
→ make
feature
→ make is
→ → do
→ → end
→ display_contents is
→ → do
→ → → io.put_character(‘(‘)
→ → → io.put_real(x); io.put_character(‘;’)
→ → → io.put_real(y); io.put_character(‘;’)
→ → → io.put_real(z);
→ → → io.put_character(‘)’)
→ → → io.put_new_line
→ → end
→ x : REAL
→ y : REAL
→ z : REAL
end end of class ATOM
Puis, dans la classe BOND, remplacez dans le constructeur, les lignes suivantes:
→ → → io.put_string(atom1.out + « %N »)
→ → → io.put_string(atom2.out + « %N »)
par
→ → → atom1.display_contents
→ → → atom2.display_contents
Puis, dans test.e, modifiez le constructeur make par les lignes:
create first_atom.make
create second_atom.make
first_atom.set_coordinates(10.0,20.05,2005.0)
Sauvegardez (Ctrl+S), compilez (Ctrl + F7) et exécutez (F5), il s’affiche:
I’m a new bond composed of :
(10.0;20.05;2005)
(0.0;0.0;0.0)
Dans ce nouvel exemple, on définit une routine display_contents
Le problème de notre classe ATOM est que les coordonnées de tous les atomes sont rigoureusement identiques. Il serait plus logique de pouvoir au moment de la création d’un objet de classe ATOM d’affecter des coordonnées différentes.
On va donc créer un autre constructeur nommé with qui possède trois arguments de classe REAL correspondant respectivement à nos coordonnées x, y et z.
class ATOM
creation
→ make, with
feature
→ with(xx, yy, zz : REAL) is
→ → do
→ → → set_coordinates(x,y,z)
→ → end
→ make is
→ → do
→ → end
→ display_contents is
→ → do
→ → → io.put_character(‘(‘)
→ → → io.put_real(x); io.put_character(‘;’)
→ → → io.put_real(y); io.put_character(‘;’)
→ → → io.put_real(z);
→ → → io.put_character(‘)’)
→ → → io.put_new_line
→ → end
→ x : REAL
→ y : REAL
→ z : REAL
end end of class ATOM
Puis mettez à jour BOND en remplaçant le constructeur make par with pour second_atom:
create first_atom.make
create second_atom.with(1.0,3.0,6.0)
Exercice 4: Ajoutons une deuxième routine qui permet d’appliquer une translation aux coordonnées de l’atome. Cette routine nommée translate possède un argument value de classe REAL. Cette routine ajoute à aux variables d’instance x,y et z de ATOM, une quantité correspondant à la valeur de value.