Académique Documents
Professionnel Documents
Culture Documents
GBM - GIS
mnkenlif@hotmail.com
1 PRESENTATION DU COURS
1.1 OBJECTIFS :
En première partie :
* Historique et définition des objectifs de la POO
* Les différents concepts de l’orienté objet
* Domaines d'application des méthodes OO
* Brève présentation de quelques méthodes d’analyse ou de modélisation OO
* Présentation des caractéristiques de quelques Langages OO et SGBDOO
En deuxième partie :
** Etude et programmation dans un langage OO comme JAVA
* Caractéristiques générales du langage Java
* Apprentissage et conception des objets, des classes, etc.
* Etude et compréhension de la programmation événementielle
* Techniques de réalisation des GUI (Interfaces Graphiques Utilisateurs)
* Manipulation des fichiers et flux
* Développement de processus (Threads)
* Accès aux Bases de données
** Projets pratiques : Conception et Développement d'Applications complètes (JAVA)
1.2 PRE-REQUIS :
• Langages de programmation professionnels : C, (C# : un atout)...
• Notions sur les structures de données abstraites
NB : L’étudiant devra remettre à chaque TP, un rapport décrivant le travail effectué, les résultats obtenus et les difficultés et
suggestions éventuelles.
2.1 INTRODUCTION
Deux types de motivations orientent actuellement les concepteurs dans le choix des méthodes de conception: la
possibilité de prendre en compte des applications et des systèmes de plus en plus complexes
[Gardarin97][Leray92][Zoller97] et le soucis de diminuer les coûts de réalisation et de maintenance. Avec l’ère des
nouvelles technologies, des réseaux informatiques et systèmes répartis, les applications ont atteint elles aussi un niveau de
complexité croissant et de ce fait, elles nécessitent à l’heure actuelle, des outils de programmation sophistiqués. On constate
que les applications dites technique, telles que la CAO, la cartographie, les systèmes de contrôle temps réel, le CoDesign…
représentent une activité croissante et nécessitent une plus grande participation des personnes aussi bien pour l'effort de
conception et validation que de maintenance et d'évolution.
Ces constats ont mis en évidence la nécessité de promouvoir l’abstraction de données, la modularité et la réutilisabilité
[Manhes98] des composants fabriqués.
Ainsi, beaucoup de méthodes ont vu le jour, chacune tentant à sa manière d’apporter une solution satisfaisante, parmi elles,
les méthodes objets (orientées objets) et leurs techniques d’analyse et de conception appropriées.
Exemple:
Objet (instance)
. Classe VOITURE .
-immatriculation
Démarrer () - marque
Rouler () -…
Stopper ()
Les principes énoncés plus haut offrent des qualités pour mettre en œuvre des méthodes rigoureuses. Ainsi, on doit
retrouver dans une approche objet au moins 4 principes obligatoires: abstraction, encapsulation, modularité, hiérarchie ;
auxquels on peut ajouter 3 principes complémentaires : typage, simultanéité, persistance.
2.2.2 ENCAPSULATION
C’est le procédé de séparation des éléments d’une abstraction qui constituent sa structure et son fonctionnement.
Elle permet de dissocier l’interface conceptuelle de la mise en œuvre d’un objet (on cache l’implémentation des méthodes).
L’encapsulation suppose également lisibilité et compréhensibilité. Les possibilités de surcharge et la modularité renforcent
la lisibilité des codes. Mais, les détails d’implantation sont généralement cachés.
2.2.3 MODULARITE
La modularité est la propriété d’un système décomposé en ensemble de modules cohérents faiblement couplés. La
modularité suppose également souplesse et modifiabilité : les objets sont faciles à changer.
2.2.5 LE TYPAGE
Le fait d’imposer la classe d’un objet de façon que les objets de types différents ne puissent pas être intervertis, ou
tout au plus ne puissent être intervertis que de façon restrictive.
2.2.6 SIMULTANEITE
Deux objets différents doivent pouvoir agir en même temps et à des endroits différents (soit sur la même machine,
soit sur des machines différentes,…).
2.2.7 PERSISTANCE
Ceci concerne la durée de vie d’un objet (important dans les BD, où les données sont disponibles pendant
longtemps).
Principes de la POO
Au fil des années, les techniques de programmation ont évolué vers une séparation entre les concepts manipulés dans les
programmes et leur représentation interne en machine, afin de mieux les structurer face à la complexité des problèmes
abordés.
Ainsi, la célèbre équation de NIKLAUS WIRTH résume ce principe :
Algorithmes + Structure de données = Programme
Les méthodes d’analyse associées à ce principe consistent alors à « diviser un problème pour mieux régner ». C’est ce que
l’on appelle la programmation dirigée par les traitements ou méthode fonctionnelle descendante. Toutefois, cette technique
atteint ses limites lorsque l’univers sur lequel opèrent les programmes évolue. La notion d’encapsulation permet alors de
CLASSE = CPOINT
Attributs X, Y : entiers
statiques Visible : booléen
Initialiser
Afficher
Méthodes Cacher
Positionner_En
P1
10,20 P2
Vrai 50,40
Deux instances de la classe CPOINT Faux
Métaclasse :
Une classe métaclasse est une classe « génératrice d’objets » non terminaux (des classes), qui regroupe les propriétés
permettant l’utilisation d’une classe sous forme d’instance.
Par exemple, dans la classe CPOINT, les méthodes peuvent être définies de cette façon :
Méhode Initialiser (x1, y1 : entiers) ; Méhode Afficher ( )
X = x1 ; Visible = vrai ;
Y = y1 ; affiche_pixel(X,Y,couleur) ;
Fin Fin
Méhode Positionner_En(px1,py1:entiers);
Méhode Cacher ( ) Cacher ( ) ;
Visible = faux ; X = px1 ;
affiche_pixel(X,Y,couleur_fond) ; Y = py1 ;
Fin Afficher ( ) ;
Fin
Les messages sont généralement associés aux classes d’utilisateurs autorisés à les manipuler, ce qui permet de mettre en
œuvre le concept de schéma à travers les méthodes.
Pour activer un objet afin qu’il exécute l’une de ses opérations, héritée ou propre, il suffit de lui envoyer un message lui
demandant de réaliser cette opération identifiée par un « sélecteur » qu’il reconnaîtra et auquel il réagira par le
comportement associé.
Il existe six principaux modes de transmission de messages :
- Transmission directe avec retour (le plus utilisé).
- Transmission directe avec suite.
- Transmission avec retour immédiat.
- Transmission indirecte avec retour différé (boite aux lettres)
- Transmission anonyme sans retour (centralisation)
- Transmission anonyme avec retour (boite aux lettres + centralisation)
2.3.3.3.3 L’interprétation des messages
La notion de message diffère quelque peu de la notion de procédure d’un langage classique. Par exemple, si l’on
dispose d’objets graphiques (boutons, icônes ou fenêtres…), le même intitulé de message peut être envoyé à deux objets
différents, car chaque objet implémente sa propre méthode de visualisation. C’est ce que l’on appelle la liaison
dynamique de message. La méthode qui doit répondre au message est recherchée au moment de l’exécution.
2.3.3.4 L’héritage
Ce concept permet de définir des classifications, de modéliser «des mondes réels» et de procéder par affinage
successif de classes prédéfinies.
Une classe peut engendrer une autre classe de telle sorte que la sous-classe possède virtuellement les champs et les
méthodes de la classe mère. Tout se passe comme si toute la classe mère était recopiée (copie virtuelle non monotone)
dans la sous classe.
L’héritage favorise le partage de connaissances (les propriétés des objets) entre objets.
Exemple : Les classes HOMME et FEMME héritent de la classe PERSONNE.
Une instance objet d’une classe hérite automatiquement des propriétés statiques (données) et dynamiques
(comportements) de sa (ses) classe (s) mère (s).
En plus des champs et méthodes héritées, une classe est définie par des propriétés qui lui sont spécifiques.
Exemple d’héritage: on peut penser qu’un cercle, en plus de ses propres particularités, possède les mêmes
caractéristiques que celles d’un point. On dira alors qu’un cercle est_un point ; la sou-classe CCERCLE héritant des
caractéristiques de la classe CPOINT créée plus haut dans ce chapitre.
POINT
TRIANGLE
TRIANGLE TRIANGLE
CERCLE
RECTANGLE ISOCELLE
ELLIPSE
TRIANGLE
RECTANGE-ISOCELLE
Grâce à la réutilisabilité, l’intégration de bibliothèques d’objets permet de construire des objets de même type, des
objets plus spécifiques, etc.
CLIENT SERVEUR
L’objet client - > demande le service
L’objet serveur - > rend le service
L’objet agent - > gère des échanges entre un client et
un serveur
AGENT
Par exemple, supposons que l’on veuille constituer une représentation par objets d’un département
informatique. Si l’on s’intéresse aux «pièces» qui composent ce département, on peut dire, que l’on retrouve des
«salles de cours», des «salles de TP», des amphithéâtres, des bureaux, etc. On aura alors une représentation semblable à
celle ci-après.
CSALLE-DE-COURS
CSALLE-MACHINE
Tables
Tables
Chaises
Chaises
Capacité d’accueil
Capacité d’accueil
Type de tableau
Type de tableau
…
Nombre d’onduleurs
Afficher Type d’imprimante
… …
Afficher
…
. CSALLE .
Tables
Chaises
Capacité d’accueil
Type de tableau
…
Afficher
…
Est_un Est_un
CSALLE-DE-COURS CSALLEMACHINE
Rétroprojecteur Nombre d’onduleurs
… Type d’imprimante
…
Afficher
…
Afficher
…
Pour terminer ce paragraphe, nous pouvons donner quelques recommandations, qui s’avèrent nécessaires si l’on
souhaite concevoir un système par objets :
♦ « Savoir revenir aux étapes précédentes », car il arrive rarement que les classes principales soient trouvées avec
exactitude, dès la première étape du processus, surtout qu’à côté des classes principales, des classes auxiliaires dues à la
programmation, viennent se greffer. Ces classes doivent être introduites naturellement en revenant à la première étape.
♦ « Prototyper rapidement avant de passer à une spécification complète », car il faut passer très rapidement à une
première ébauche du logiciel, qui permettra de spécifier le logiciel. Mais attention à une programmation sans
spécification.
♦ « Penser abstrait », car la conception par objets permet de définir des modèles du monde réel par abstraction des
classes et des opérations indépendantes de la nature des objets manipulés.
♦ Et enfin, « penser local », en ne cherchant pas à structurer globalement l’ensemble du système, mais en définissant
des opérations de portée locale.
2.7 CONCLUSION
L'idée majeure qui préside dans le concept objet consiste à conserver la même philosophie depuis l'analyse des besoins à
partir du monde réel, la spécification jusqu'à sa réalisation, en l'occurrence celle des objets.
Pour conclure ce chapitre, nous pouvons donner quelques recommandations, qui s’avèrent nécessaires si l’on souhaite
concevoir un système par objets :
♦ « Savoir revenir aux étapes précédentes », car il arrive rarement que les classes principales soient trouvées avec
exactitude, des la première étape du processus, surtout qu’à coté des classes principales, des classes auxiliaires dues à la
programmation, viennent se greffer. Ces classes doivent être introduites naturellement en revenant à la première étape.
♦ « Prototyper rapidement avant de passer à une spécification complète », car il faut passer très rapidement à une
première ébauche du logiciel, qui permettra de spécifier le logiciel. Mais attention à une programmation sans spécification.
♦ « Penser abstrait », car la conception par objets permet de définir des modèles du monde réel par abstraction des
classes et des opérations indépendantes de la nature des objets manipulés.
♦ Et enfin, « penser local », en ne cherchant pas à structurer globalement l’ensemble du système, mais en définissant
des opérations de portée locale.
3.2 INTRODUCTION
Définition initiale de Sun Microsystems: "Java est un langage simple, orienté objet, distribué, robuste, sûr,
indépendant des architectures matérielles, portable, de haute performance, multithread et dynamique".
Lors de la création du langage Java, il avait été décidé que ce langage devait répondre à 5 objectifs :
- utiliser une méthodologie orientée objet,
- permettre à un même programme d'être exécuté sur plusieurs systèmes d'exploitation différents,
- pouvoir utiliser de manière native les réseaux informatiques,
- pouvoir exécuter du code distant de manière sûre,
- être facile à utiliser et posséder les points forts des langages de programmation objet comme le C++.
Le langage JAVA est donc un langage Orienté Objet devenu incontournable pour tout développement important
(notamment sur Internet/Intranet/Extranet). Il permet de développer des applications capables de s’exécuter sur
n’importe quelle plateforme (Windows 95/98/NT/2000/XP/2003/Vista/2008/2012, Unix, Mac-OS, OS400, Amiga-OS,
Next, ...) dotée d’une Machine Virtuelle Java (MVJ).
Plusieurs types de programmes peuvent être générés par JAVA :
• Les Applets (prononcer « Appelletes ») prévues pour fonctionner à l’intérieur d’une page Web, dans un logiciel
de Navigation ;
• Les Applications qui sont des programmes autonomes n’ayant besoin que de la MVJ ;
• Les servlets qui tournent sur les serveurs (en environnement client-serveur) ;
• Les midlets pour des petits systèmes ou équipements.
Java se décline en plusieurs types d’environnements de réalisation :
• JSE (Java Standard Edition)
• JME (Java Mobile Edition) : version allégée de JSE, adaptée en général aux appareils de « faible puissance ».
• JEE (Java Enterprise Edition)
Le langage est pratiquement stable depuis le JDK 1.0 ; les bibliothèques de classes fournies se sont agrandies et ont
changé en partie. À partir de la version 1.2, le JDK a été renommé en J2SDK (Java 2 Software Development Kit / kit de
développement de logiciels Java 2) et on appelle souvent ces versions Java 2.
Du fait de l'accroissement des bibliothèques et des changements entre versions, la compatibilité est assurée dans un seul
sens : les programmes Java compilés avec une version antérieure du JDK (par exemple 1.2) continueront à fonctionner
avec un JRE plus récent (par exemple 1.9), mais le contraire n'est pas vrai.
Java est habituellement compilé vers une machine virtuelle standardisée, sous forme de bytecode. Cette machine peut
fonctionner avec un interpréteur, un compilateur just-in-time (à la volée), ou, le plus couramment, avec un mélange des
deux. Il existe des variantes de ce schéma :
• permettant de compiler le langage Java nativement, c’est-à-dire de produire un exécutable capable de
fonctionner hors de l'environnement Java, et même de produire un exécutable capable de fonctionner dans
l'environnement CLR de Microsoft .NET, grâce à la variante J# de Java, créée par Microsoft.
• permettant de produire un exécutable Java à partir d'autres langages, comme Python à l'aide du
compilateur Jython, ou encore Groovy.
Version interprétée
Il existe plusieurs versions interprétées de Java (langages de scripts s'exécutant sur une JVM): beanshell et Groovy
sont standardisés au sein du JCP (Java Community Process). Jython, JRuby et d'autres langages de scripts proposent
des langages sur ce même principe. L'interpréteur de ces langages peut être embarqué dans une application Java pour la
rendre scriptable. A noter qu'à partir de Java 6, le moteur Rhino (JavaScript) est embarqué dans la JRE.
• Initialisation
Lorsqu’un objet est créé, tous ses champs sont initialisés à une valeur nulle (false pour un booléen, null pour une
référence d’objet et 0 pour une valeur). Le constructeur est alors invoqué. Son travail se fait en trois phases.
1. Invocation éventuelle du constructeur de la classe mère ;
2. Initialisation des champs en utilisant la valeur d’initialisation spécifiée lors de leur déclaration ;
3. Exécution du corps du constructeur.
Il est vivement recommandé d’initialiser explicitement toutes les variables dès leur déclaration, plutôt que de les
déclarer d’abord et de ne les initialiser qu’ensuite.
Si vous cherchez à les utiliser entre le moment où elles sont déclarées et le moment où elles sont utilisées, vous risquez
des mauvaises surprises lors de l’exécution.
Heureusement, le compilateur JAVA signale la plupart de ces tentatives d’utilisation illicites de variables non
initialisées.
• On distingue en général 4 types de méthodes : les constructeurs (constructor), les méthodes d’accès (ou
accessor ; forme getXXX) et les méthodes d’altération (ou mutator ; forme setXXX) et les destructeurs.
Notez qu’il est toujours prudent de prévoir une méthode d’accès pour chacun des champs privés d’un objet. En effet il
ne faut pas oublier qu’il doit toujours être possible de modifier l’implémentation d’une classe de manière transparente
pour son utilisateur.
En général, les attributs d’une classe sont déclarés privés ou protégés, ce qui signifie que seuls des objets de la classe ou
de ses sous-classes peuvent les lire et les modifier. Pour accéder à ces attributs de l’extérieur, on ajoute à la classe des
méthodes spécialement conçues à cet effet, que l’on appelle « accesseurs » – et parfois « modifieurs » quand il s’agit
de modifier la valeur.
• Les méthodes d'accès "get" et "set" servent à encapsuler la représentation des données internes dans la fiche des
variables membre privées.
• Un constructeur n’est rien d’autre qu’une méthode sans valeur de retour portant le même nom que la classe. La
notion de constructeur permet d’automatiser le mécanisme d’initialisation d’un objet. Un constructeur est une
méthode spéciale qui affecte toutes les ressources de la classe.
La création d’un objet entraîne toujours par ordre chronologique les opérations suivantes :
- initialisation par défaut (implicite) de tous les champs de l’objet ;
- initialisations explicites lors de la déclaration de champs ;
- exécution des instructions du corps du constructeur.
• Les variables d’instances (non-static) sont propres à chaque objet, instance d’une classe.
• Les variables de classe (static) sont associées à la classe. Il n’y a qu’une seule copie de cette variable sans égards
aux nombres d’instances de cette classe. Il s’agit en fait d’une donnée globale partagée par toutes les instances d’une
même classe.
• Les méthodes de classe (static) ne sont pas accompagnées d’un argument implicite this et ne peuvent utiliser les
méthodes et variables d’instances de la classe.
Pour appeler une méthode statique d’une classe, on utilise en général le nom de la classe plutôt qu’une de ses
instances. Cela évite d’avoir à appeler le constructeur de la classe et de construire une instance. L’intérêt des
méthodes statiques est en effet de pouvoir être appelées alors qu’on ne dispose pas d’un objet de la classe dans
laquelle elle est définie.
• Les méthodes d’instance d’une classe sont accompagnées d’un argument implicite this qui identifie l’objet sur
lequel elles opèrent.
• Les objets sont créés avec le mot réservé new, qui invoque un constructeur de classe (méthode) avec éventuellement
une liste d’arguments. Ils peuvent être détruits avec la méthode dispose().
• En général, les objets ne sont pas explicitement détruits. Le « Ramasse-miettes » (« Garbage collector ») de Java
détruit automatiquement les objets qui ne sont pas utilisés.
• La zone du « tas », « garbage collectée » : La zone du tas est l’endroit ou « vivent » les objets d’un programme
JAVA. À chaque création d’objet par l’opérateur new, la mémoire consommée par cet objet est allouée dans cette
zone du tas. Le langage JAVA ne permet pas de libérer explicitement ou de dés-allouer directement cette mémoire.
Par contre, l’environnement d’exécution conserve les références vers chaque objet sur le tas et libère
automatiquement la mémoire occupée par les objets qui ne sont plus référencés. Ce processus est appelé «
ramassage des déchets ».
• Un finaliseur est une méthode automatiquement appelée par le Garbage collector juste avant la destruction d'un
objet.
• Si une classe ne définit pas de constructeur, Java procure un constructeur par défaut qui se contente
d’allouer un emplacement mémoire.
• L'héritage est implémenté en utilisant le mot clé extends.
• Une classe peut hériter de méthodes et de variables non préfixées par private, d’une autre classe en se définissant
comme sous-classe de cette classe à l’aide de la clause extends.
• Jav.lang.Object est la super classe par défaut, c’est la classe racine, elle n’a pas de super classe.
La classe Object sert à définir l’objet le plus générique qui soit. Toute classe peut être conçue comme héritant de la
classe Object. La classe Object dispose de quelques méthodes qu’on peut soit utiliser telles quelles soit redéfinir.
Quelques méthodes de la classe Object :
public boolean equals(Object obj)
Teste l’égalité des valeurs de l’objet receveur et de l’objet passé en paramètre.
public int hashCode()
Retourne le code de hachage de cet objet, pour le ranger dans une Hashtable.
public Object clone() throws CloneNotSupportedException
Permet d’effectuer une copie superficielle des objets. Cependant, il existe une interface destinée à faciliter la gestion du
clonage (copie profonde) des objets. Il s’agit de l’interface cloneable qu’on peut implémenter, puis redéfinir la méthode
clone.
public final Class getClass()
Retourne un objet de type Class qui représente la classe de cet objet et contient notamment le nom de la classe,
accessible par getName().
public void finalize() throws Throwable
Finalise l’objet lors de l’appel du garbage collector.
Parmi ces méthodes, on peut citer quelques-unes qui sont importantes : « toString » et « equals ». La méthode
toString fournit une chaîne (nom de la classe + adresse de l’objet en hexadécimal précédé de @) tandis que la
méthode equals compare les adresses des deux objets concernés.
• La redéfinition est le fait de redéfinir une méthode héritée de sa superclasse. Il s’agit en fait de donner à une classe
spécifique une méthode qui porte le même nom et possède la même signature qu’une méthode d’un objet de la
classe générique dont elle hérite, mais dont le code est différent de cette méthode plus générique. Dans le cas où la
méthode plus générique est abstraite, on ne parle pas de redéfinition mais d’instanciation.
• La surcharge (ou surdéfinition = overload) des méthodes est le fait de déclarer plusieurs méthodes de même nom,
mais qui se différencient par leur signature (type de retour ou liste des arguments). La sur-définition est possible
dans une même classe ou dans des classes dérivées. Cette notion de polymorphisme permet de manipuler des objets
sans connaître (tout à fait) le type (classe, sous-classes ou sur-classes). Ce concept vient compléter l’héritage.
• Le polymorphisme offre la possibilité à deux objets distincts, mais reliés, de recevoir le même message et d'y réagir
presque différemment.
En plus, avec le polymorphisme un objet d’une classe peut être manipulé comme s’il appartenait à une autre
classe. En JAVA, le moyen de réaliser cela consiste à « caster » une classe en une autre. On parle aussi de
conversion de type. On ne peut « caster » que d’un type de base dans un autre, ou alors d’une classe vers une autre
classe plus générique ou plus spécifique. Toute autre tentative de « cast » est acceptée à la compilation mais lève
l’exception ClassCastException lors de l’exécution.
• Les règles du polymorphisme en Java :
- Largeur CLASSES
- Hauteur - Rayon
Surface ( ) Surface ( )
Périmetre ( ) Perimetre ( )
INSTANCES
Disq1
Rect 1 (Objets)
Rect 3 Disq2 Disq3
Rect 2
Rectangle Disque
• Passage de paramètres
En JAVA, le passage de paramètres s’effectue par valeur (la transmission d’un argument à une méthode et celle de son
résultat ont toujours lieu par valeur). Cela signifie que, lors de l’appel d’une méthode, JAVA effectue une copie de la
variable provenant de la méthode appelante et passée en paramètre. C’est sur la copie que travaille la méthode appelée. La
portée de cette copie est limitée à la méthode dans laquelle elle est passée en paramètres.
Par conséquent, si la valeur de la variable est modifiée dans la méthode appelée, cette modification n’est pas répercutée
dans la méthode appelante, à moins que la variable ne soit renvoyée en valeur de retour et affectée explicitement à la
variable de la méthode appelante.
Pour le cas des objets transmis en argument : une méthode d’un objet A est autorisée à accéder aux champs privés d’un
autre objet B de la même classe. On dit que en Java « l’unité d’encapsulation est la classe et non l’objet ». Bien entendu
lorsqu’une méthode d’une classe T1 reçoit en argument un objet de classe T2, différente de T1, elle n’a pas accès aux
champs ou méthodes privées de cet objet.
• Autoréférence par le mot-clé « this » : il permet de faire référence à un objet dans sa globalité (et non plus à
chacun de ses champs). Cas par exemple ou l’on souhaite transmettre un objet en argument d’une autre méthode. Pour
l’appel d’un constructeur au sein d’un autre constructeur, on peut aussi faire appel au mot-clé this que l’on utilise cette
fois comme un nom de méthode ; d’une manière générale, l’appel this (…) doit obligatoirement être la première
instruction du constructeur.
• La récursivité des méthodes : elle est autorisée par Java. Elle peut être directe (une méthode comporte dans sa
définition au moins un appel à elle-même) ou croisée (l’appel d’une méthode entraine l’appel d’une autre méthode qui à
son tour appelle la méthode initiale).
• Les classes internes : elles ont une définition située à l’intérieur de la définition d’une autre classe. Malgré certaines
ressemblances avec la notion d’objet membre, elle ne doit surtout pas être confondue avec elle, même si elle peut être
utilisée dans ce contexte.
Class E // définition d’une classe,usuelle (dite alors externe)
{… … … // méthodes et données de la classe E
Class I // définition d’une classe interne à la classe E
{… … // méthodes et données de la classe I
}
… … … // autres méthodes et données de la classe E
}
Une classe interne peut être déclarée static pour pouvoir la rendre autonome.
Une classe interne peut être locale même à une (à l’intérieur d’une) procédure.
• Constructeurs de copie
Examinons le code suivant :
Voiture mavoiture = new Voiture();
Voiture autre = mavoiture;
La seconde instruction consiste à créer une nouvelle référence, nommée autre, à laquelle est affectée la valeur de
la référence mavoiture.
• Les clones
Plutôt que d’utiliser un constructeur de copie comme nous venons de le présenter, un usage répandu en JAVA consiste à
utiliser une méthode clone() qui se présente de la manière suivante :
public class Voiture
{
protected byte nbPortes;
protected long cylindree;
protected Carrosserie maCarros;
/*** Constructeur de Voiture */
public Voiture(byte nbp, long cyl, Carrosserie car)
{
maCarros = car;
nbPortes = nbp;
cylindree = cyl;
}
/*** méthode de clonage : @retourn un clone de type Voiture */
public Voiture clone()
{
Voiture retour = new Voiture(nbPortes, cylindree,
new Carrosserie(maCarros));
return retour;
}
}
On l’appelle avec l’instruction : Voiture copie = mavoiture.clone();
Cet usage est encouragé en JAVA.
La notion de clone permet d’effectuer explicitement la recopie de tous les champs d’un objet dans un autre
objet de même type. Toutefois, si les données sont convenablement encapsulées, il n’est pas possible d’y
accéder directement.
• L’avantage du langage à objets est que le code est réutilisable. Grâce à l’héritage, on peut étendre une classe sans
avoir à la réécrire complètement (et même sans connaître les détails de son implémentation), alors que l’utilisation d’un
langage classique nous obligerait à modifier le code source (donc à bien le comprendre).
• La réflexivité
Ceci concerne le fait qu’un objet puisse consulter la structure de la classe à laquelle il est rattaché.
La réflexivité se traduit en JAVA par un ensemble de mécanismes qui augmentent considérablement la puissance du
langage. Un objet peut par exemple s’auto-interroger pour savoir quel est son type, il peut se demander s’il hérite d’un type
particulier, il peut récupérer le nom de sa classe dans une chaîne de caractères ou encore sauvegarder son état complet dans
une autre chaîne de caractères.
L’ensemble de ces mécanismes est assez disparate. Vous pouvez utiliser :
– instanceof : opérateur qui vérifie si un objet est d’un type donné ou de l’une des sous-classes de ce type ;
– getClass() : méthode de la classe Object qui renvoie le type de l’objet (sous la forme d’un objet, instance de la classe
« Class », dans laquelle toute classe est décrite réflexivement). La classe Class possède notamment une méthode
getName() qui renvoie le nom de la classe et s’avère bien utile ;
– Serializable : interface qui permet la persistance ;
Les variables d’environnement doivent être correctement initialisées :
• JAVA_HOME répertoire de base du JDK.
• PATH répertoire contenant le compilateur et l’interprétateur (par exemple : $JAVA_HOME/bin).
• CLASSPATH répertoire contenant les classes (par exemple : $JAVA_HOME/lib).
Le classpath est une variable d’environnement qui permet de spécifier l’ensemble des chemins dans lesquels JAVA
doit aller chercher les classes susceptibles d’être nécessaires à l’exécution d’un code.
Sous UNIX et tous les systèmes d’exploitation apparentés, en csh et tcsh, on positionne le classpath à l’aide de la
commande : setenv CLASSPATH chemin1:chemin2:... :cheminN.
En bash, on écrit : export CLASSPATH=chemin1:ch2:... :cheminN.
• Sérialisation
On appelle « sérialisation » le processus consistant à écrire le contenu d’un objet dans un fichier pour pouvoir le
recharger lors d’une exécution ultérieure dans l’état où il était au moment de sa sauvegarde.
Pour qu’on puisse appliquer la sérialisation à ses objets, une classe doit implémenter l’interface Serializable. Il faut
aussi que tous ses attributs implémentent l’interface Serializable de même que les attributs de ces attributs, etc.
Ceci est une solution pour sauvegarder un ensemble (ou tous les) objets de notre programme.
[wwwJavaMem]
Figure 8. Etapes de compilation et exécution en Java
Pour peu qu'une plate-forme (windows, Unix, Linux, Amiga, ...) possède une machine virtuelle fonctionnant sous son
système, celle-ci est capable d'exécuter n'importe quelle application Java!
C’est ainsi que l'ensemble des navigateurs permettant d'utiliser des applets possèdent une machine virtuelle.
Avantages/Inconvénients du bytecode Java
- Code portable au niveau binaire
- Moins efficace que du code natif
L’outil JavaDoc
Il s’agit d’un utilitaire associé à JAVA qui génère automatiquement une documentation de code JAVA au format
HTML. La documentation fait apparaître l’ensemble des classes et leurs relations hiérarchiques avec différents points
d’entrée, par index, par package ou par arborescence d’héritage. Pour chaque classe apparaissent tous ses attributs et
méthodes, avec la signature complète de chaque méthode. Il s’agit d’un outil très intéressant présent dans le JDK,
• Le troisième programme Bonjour avec paramètres en ligne de commande est présenté ci-dessous :
class TestCommande
{
public static void main(String[] args)
{
string ch ;
System.out.println("Bonjour et Merci de choisir Java");
for (int i = 0; i < args.length; i++)
{
//system.out.print(i == 0 ? args[i] : " " + args[i]);
if (i == 0) ch = arg[i];
else ch = " " + args[i];
system.out.print(ch);
}
System.out.println();
}
}
3.13 STRUCTURES
3.13.1 LES LITTÉRAUX
Lorsque vous insérez une valeur littérale dans un programme, le compilateur sait exactement à quel type il se réfère. Parfois
cependant, il peut arriver que le type soit ambigu. Quand c’est le cas, vous devez guider le compilateur en adjoignant des
informations supplémentaires sous forme de caractère associé à la valeur littérale. Ces caractères sont présentés ci-après :
public class Literals {
char c = 0xffff; // max char hex value
byte b = 0x7f; // max byte hex value
short s = 0x7fff; // max short hex value
int i1 = 0x2f; // Hexadecimal (lowercase)
int i2 = 0X2F; // Hexadecimal (uppercase)
int i3 = 0177; // Octal (leading zero)
// Hex and Oct also work with long.
long n1 = 200L; // long suffix
long n2 = 200l; // long suffix
long n3 = 200;
//! long l6(200); // not allowed
float f1 = 1;
float f2 = 1F; // float suffix
float f3 = 1f; // float suffix
float f4 = 1e-45f; // 10 to the power
float f5 = 1e+9f; // float suffix
double d1 = 1d; // double suffix
double d2 = 1D; // double suffix
double d3 = 47e47d; // 10 to the power
} ///:~
3.13.2 EXERCICES
Exercice 1 :
Créer la classe qui définit une abstraction des nombres complexes.
Class complex
private re, im :real ;
function cons (re, im : real) return complex ;
function add (L, R : complex) return complex ;
…. … …
fin class complex ;
1-) On souhaite développer une petite classe offrant les services de base que sont la lecture d’entiers, de flottants de caractères …
// nom du fichier = «Clavier.java »
// classe fournissant des fonctions de lecture au clavier -
import java.io.* ;
public class Clavier
{ public static String lireString () // lecture d'une chaine
{ String ligne_lue = null ;
try
{ InputStreamReader lecteur = new InputStreamReader (System.in) ;
BufferedReader entree = new BufferedReader (lecteur) ;
ligne_lue = entree.readLine() ;
}
catch (IOException err)
{ System.exit(0) ;
}
return ligne_lue ;
}
public static float lireFloat () // lecture d'un float
{ float x=0 ; // valeur a lire
try
{ String ligne_lue = lireString() ;
x = Float.parseFloat(ligne_lue) ;
}
catch (NumberFormatException err)
{ System.out.println ("*** Erreur de donnee ***") ;
System.exit(0) ;
}
return x ;
}
public static double lireDouble () // lecture d'un double
Java 1.0 Java 1.1 Java 1.2 J2SE 1.3 J2SE 1.4 J2SE 5
Nombre de de packages 8 23 59 76 135 166
Nombre de classes 201 503 1520 1840 2990 3280
Méthodes 1545 3 85 15 060
4.1.2 LES PAQUETAGES POUR CRÉER DES INTERFACES GRAPHIQUES PLUS INTÉRESSANTES
Trois groupes de packages permettent de gérer les interfaces graphiques :
- AWT : Abstract Window Toolkit / Abstract Widget Toolkit. AWT utilise des "composants lourds", c'est à dire
utilisant les ressources du système d'exploitation. Ce qui lui assure une bonne performance.
- Swing (intégré à partir de la version 1.2 du JDK). Alors que swing utilise des "composants dits légers", n'utilisant
pas ces ressources. Swing est plus robuste que l'AWT, plus portable, et plus facile à utiliser. Swing ne remplace
Il s’agit d’un cas simple d’application graphique à l’aide des classes du paquetage Swing. Elle ne fait pas grand chose, mais
présente tout de même l’essentiel qu’on doit retrouver dans un tel programme :
1. importation des packages pertinents
2. initialisation du (ou des ) “container" de base
3. affichage du “container"
4. sécurisation du processus (thread)
Nous avons ici importé le package “Swing” principal (seul utile dans notre exemple).
import javax.swing.*;
Mais il faut noter que la plupart des programmes auront besoin d’importer deux packages AWT :
import java.awt.*;
import java.awt.event.*;
try {
//<-- Créer un flux pour écrire dans un fichier. Le fichier
//n'est pas spécifié puisque ce n'est pas essentiel pour l'exemple.
fos = new FileOutputStream(...);
fos.write(a); //'a' aurait reçu une valeur ultérieurement
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
//Fermer le flux, qu'il y ait une exception lancée ou pas
if(fos != null) fos.close();
}
4.4.1 INTRODUCTION
Pour prendre en charge certaines fonctionnalités, la plupart des langages de programmation reposent sur des
bibliothèques déjà construites. Par exemple, le langage C (à l’origine) n'intégrait pas la prise en charge directe des fonctions
d'E/S. Le JDK dispose d'une bibliothèque très impressionnante qui inclut la connectivité des bases de données, la
conception GUI, les E/S et la programmation en réseau. Bien que le JDK contienne de nombreux paquets de prise en
charge, dix d'entre eux méritent une présentation spécifique.
Langage = Noyau principal du langage Java (lang)
Utilitaires = Prise en charge des structures de données utilitaires (util)
E/S = Prise en charge de divers types d'entrée/sortie (IO)
Réseau = Prise en charge de TCP/IP et programmation des sockets (net)
AWT = Conception GUI et gestion des événements (awt)
Sécurité = Prise en charge de la sécurité par cryptographie (security)
RMI = Prise en charge de la programmation distribuée (rmi)
SQL = Prise en charge de l'interrogation des bases de données avec SQL (sql)
Reflection = Donne des informations sur les classes à l'exécution
Texte = Prise en charge de l'internationalisation
Voici une liste non exhaustive des propriétés et méthodes de la classe Object :
package java.lang;
public class Object {
public final Class<?> getClass() { . . . }
public String toString() { . . . }
public boolean equals(Object obj) { . . . }
public int hashCode() { . . . }
protected Object clone()
throws CloneNotSupportedException { . . . }
public final void wait()
throws IllegalMonitorStateException,
InterruptedException { . . . }
public final void wait(long millis)
throws IllegalMonitorStateException,
InterruptedException { . . . }
public final void wait(long millis, int nanos) { . . . }
throws IllegalMonitorStateException,
InterruptedException { . . . }
public final void notify() { . . . }
throws IllegalMonitorStateException
public final void notifyAll() { . . . }
throws IllegalMonitorStateException
protected void finalize()
throws Throwable { . . . }
}
Un objet qui utilise la méthode clone fait simplement une copie de lui-même. Pour cela, une certaine quantité de mémoire
est affectée au clone, puis le contenu de l'objet initial est copié dans l'objet clone. Par exemple, nous voulons obtenir une
Un exemple simple illustre l'implémentation de l'interface Enumeration. Il contient une classe appelée canEnumerate, qui
implémente l'interface Enumeration. Une occurrence de cette classe peut être utilisée pour imprimer tous les éléments d'un
objet Vector (v dans ce cas).
canEnumerate enum = v.elements( );
while (enum.hasMoreElements( ))
{
System.out.print (enum.nextElement( ));
}
Un objet Enumeration est limité car il ne peut être utilisé qu'une seule fois. L'interface ne dispose pas de méthode
permettant de revenir sur l'élément précédent. Ainsi, une fois la totalité de la liste énumérée, l'objet est consommé.
while(tokenizer.nextToken() != StreamTokenizer.TT_EOF){
if(tokenizer.ttype == StreamTokenizer.TT_WORD) {
System.out.println(tokenizer.sval);
} else if(tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
System.out.println(tokenizer.nval);
} else if(tokenizer.ttype == StreamTokenizer.TT_EOL) {
System.out.println();
}
}
La classe StreamTokenizer permet de reconnaître des identificateurs, des nombres, des chaînes entre côtes, et autre
styles de commentaires. Il est possible de spécifier que certains caractères puissent être interprétés comme des espaces
blancs ou des caractères de début (begin) ou de fin (end), etc. tout ceci est configuré dans votre StreamTokenizer
avant le début de l’analyse du contenu.
4.5.2 EXEMPLES :
♦ Nous présentons un exemple de programme utilisant un tableau d’objets de type Point :
public class TabPoint
{ public static void main (String args[])
{ Point [] tp ;
tp = new Point[3] ;
tp[0] = new Point (1, 2) ;
tp[1] = new Point (4, 5) ;
tp[2] = new Point (8, 9) ;
for (int i=0 ; i<tp.length ; i++)
tp[i].affiche() ;
}
}
class Point
{ public Point(int x, int y)
{ this.x = x ; this.y = y ;
}
public void affiche ()
{ System.out.println ("Point : " + x + ", " + y) ;
}
private int x, y ;
}
♦ Exemple de programme qui détermine le nombre d’élèves ayant une note supérieure à la moyenne de la classe.
public class Moyenne
{ public static void main (String args[])
{ int i, nbEl, nbElSupMoy ;
double somme ;
double moyenne ;
System.out.print ("Combien d'eleves ") ;
nbEl = Clavier.lireInt();
double notes[] = new double[nbEl] ;
for (i=0 ; i<nbEl ; i++)
{ System.out.print ("donnez la note numero " + (i+1) + " : " ) ;
notes[i] = Clavier.lireDouble() ;
}
for (i=0, somme=0 ; i<nbEl ; i++) somme += notes[i] ;
moyenne = somme / nbEl ;
System.out.println ("\nmoyenne de la classe " + moyenne) ;
Exercice 3 :
Modifier le programme précédent pour pouvoir effectuer le TRI des notes saisies avant de les afficher.
Exercice 4 :
Effectuer le produit vectoriel entre deux vecteur de réels.
Exercice 5 :
Modifier le programme précédent en le rendant plus dynamique et en créant une interface graphique utilisateur à cet effet. On
mettra l’accent sur la qualité et la convivialité de l’interface (saisie/édition des matrice, etc.). A cet effet, le gestionnaire de mise en
forme (Layout manager) pourra être utilisé pour faciliter la présentation : BoerderLayout, GridLayout, FlowLayout, etc.
Exercice 6 :
Exercice 7 :
Résoudre le système d’équation linéaire AX=B ; //A, X, B étant des matrices (confère cours analyse numérique)
do
{ System.out.print ("Numero de l'entier recherche : ") ;
num = Clavier.lireInt() ;
if (num == 0) break ;
int rang = 4*(num-1) ;
if ( (rang>0) && (rang<taille))
{ entree.seek (rang) ;
n = entree.readInt() ;
System.out.println (" valeur = " + n) ;
}
else { System.out.println ("entier inexistant") ;
continue ;
}
}
while (num != 0) ;
entree.close () ;
System.out.println ("*** fin consultation fichier ***");
}
}
do
{ ligne = entree.readLine() ;
if (ligne != null) System.out.println (ligne) ;
}
while (ligne != null) ;
entree.close () ;
System.out.println ("*** fin liste fichier ***");
}
}
import java.io.* ;
import java.util.* ; // pour StringTokenizer
public class Lectxt3
{ public static void main (String args[]) throws IOException
{ String nomfich ;
double x, som = 0. ;
System.out.print ("donnez le nom du fichier a lister : ") ;
nomfich = Clavier.lireString() ;
BufferedReader entree = new BufferedReader (new FileReader (nomfich)) ;
System.out.println ("Flottants contenus dans le fichier " + nomfich + " :") ;
while (true)
{ String ligneLue = entree.readLine() ;
if (ligneLue == null) break ;
StringTokenizer tok = new StringTokenizer (ligneLue, " ") ; // espace separateur
int nv = tok.countTokens() ;
for (int i=0 ; i<nv ; i++)
{ x = Double.parseDouble (tok.nextToken()) ;
som += x ;
System.out.println (x + " ") ;
}
Exercice 9 :
Ecrire un programme qui lit le fichier texte créé plus haut (contenant les nombres et leurs carrés) et en extrait les différents
nombres et leurs carrés.
Remarque :
L’objet in est un objet constant appartenant à la classe InputStream. On peut connecter un flux texte au clavier en
procédant ainsi :
InputStreamReader entree = new InputStreamReader (System.in);
On pourra lire des lignes de texte en procédant ainsi :
BufferedReader entree = new BufferedReader (lecteur);
C’est d’ailleurs ainsi que nous procédons dans les classes de lecture au Clavier.
Exercice 10 :
1-) Ecrire un programme généralisé qui crée un fichier LICGI de 100 étudiants ayant les propriétés :
« nom : string[18] ; classe : string[4] ; note1 : 0..20 ; note2 : 0..20 ; moy : real ; reussi : boolean ; classement : int ; »
Le nom sera une chaîne de caractères construite de façon aléatoire et de longueur [5..18]. La classe aura aléatoirement la
valeur : GI1, GI2 , GI3. Les notes des valeurs aléatoires [0..20], la moyenne initialisée à -l et reussi initialisé à False.
N.B : On pourra enregistrer chaque étudiant dans un fichier texte sur une ligne.
2-) Ecrire le programme qui calcule la moyenne pour chaque étudiant, et met le champ réussi à True si la moyenne est ≥10.
3-) Ecrire le programme qui affiche les étudiants de DUTGI ayant réussi. On vérifiera la moyenne.
3-) Ecrire le programme qui effectue le classement des étudiants de DUTIG crées précédemment.
4-) Ecrire le programme qui crée un fichier trié alphabétiquement pour chaque classe (TRI par nom, prenom et classe), en utilisant le
fichier précédent.
4.6.5 GESTION GLOBALE DES FICHIERS PHYSIQUES (NIVEAU SYSTÈME) : CLASSE « FILE »
Elle permet des opérations concernant le fichier dans sa globalité (sur le disque), et non plus chacune des
informations qu’il contient. On pourra créer, supprimer, ou renommer un fichier ou un répertoire, tester l’existence d’un
fichier ou d’un répertoire, obtenir des informations relatives aux protections ou aux dates de modification, lister les noms
de fichiers d’un répertoire …
Exercice 11 :
1-) Ecrire un programme qui recherche tous les fichiers temporaires sur le disque et affiche les statistiques par type (*.bak, *.tmp,
*.log, *.swp, etc.) et par catégorie (nombre, taille, etc.)
2-) Ecrire le programme qui les efface après confirmation de l’utilisateur. L’accent sera mis sur la qualité et la convivialité des
interfaces.
Dans cette partie, nous donnons une présentation des possibilités de la plateforme JSE qui dispose de packages pour
développer des programmes offrant de belles interfaces graphiques utilisateurs (GUI).
En effet, la “boite à outils” Swing, incluse dans la plateforme Java SE, fournit un ensemble assez riche de composants GUI.
En plus, Swing offre beaucoup plus de fonctionnalités, bien au-delà d’une simple “boite à outils" standard.
On peut utiliser Swing qui offre un ensemble de composants, pour construire des programmes avec interfaces
graphiques conviviales. Ceux-ci apporteront une grande interactivité à vos applications Java. Swing contient tout ce
qu’on peut attendre d’une “boite à outils”, supports et primitives d’interfaces modernes : table controls, list controls,
tree controls, buttons et labels … / undo support, customizable text package, integrated internationalization and
accessibility support ... / drag and drop, event handling, customizable painting, window management, etc. Bref, une
grande richesse en termes de fonctionnalités graphiques. Nous allons décrire les élements fournis par Swing et JFC.
* Composants GUI Swing
Ceci va des composants simples tels que les cases à cocher et les boutons, aux composants complexes tels
que zones textes, arbres et tables d’opération ou encore explorateurs de fichiers. Des fonctionnalités comme la
lecture de textes dans un format, ou encore la lecture de mots de passe sont intégrées aux champs de saisie. Bien
sûr, on a également la possibilité de créer ses propres composants.
* Java 2D
Pour faciliter l’intégration des données multimedia (figures, images, animations, diverses synthèses ...) à
votre application, vous pouvez utiliser l’API Java 2DTM.
* Support (creation et intégration) des modules d’extension “Look-and-Feel”
Il est possible de metre en oeuvre ses propres look-and-feel, de spécifier ceux disponibles sur votre plateforme
système ou encore d’exploiter ceux (des centaines) disponibles avec Swing (grâce par exemple au module GTK+).
* Echange de données
Ceci est possible grace aux mécanismes de transfert disponibles Via : couper, copier, coller, glisser,
deposer, etc. (cut, copy, paste, and drag and drop). Ces possibilités offertes dans Swing sont essentielles pour
toute application, lorsqu’on veut faire communiquer les applications entre elles, ou les composants au sein
d’une même application.
* Internationalisation
Il est possible pour le développeur de construire une application qui interagit avec le monde entier en
tenant compte de la langue et des conventions culturelles de chacun. Le gestionnaire de mise en forme de
Swing facilite la prise en compte de diverses langues manipulant des milliers de caractères qui pourront être
facilement supportées (incluant : Japonais, Chinois, Coréen, etc.)
* Gestion d’Accessibilité
Ceci prend en compte les technologies de présentation des informations de la façon la plus accessible
(technologies d’assistance: voie, Braille, Clavier assisté dynamiquement ...). Cette API rend disponible cette
technologie.
* Annulation et Rétablissement (undo Framework)
Swing dispose d’une microarchitecture permettant au développeur de fournir des supports pour effectuer
les actions annuler (undo) et rétablir/refaire (redo). L’opération est disponible en standard dans les
composants « text » de Swing. Pour les autres composants, Swing supporte un nombre « illimité » d’actions
pour « annuler » et « rétablir », et il est facile de les adapter à sa propre application. Par exemple, vous pouvez
très bien activer facilement annuler pour l’ajout et et la suppression d’élements dans un objet « table ».
* Support de Déploiement Flexible
Les programmes Java peuvent être déployés comme application ordinaire, ou sur des interfaces Web
(Applets) à l’aide des « Plug-in Java », qui supportent pratiquement tous les navigateurs Internet. Le
programmeur dispose à cet effet de l’outil “Java Web Start”.
La plupart des programmes utilisent juste une partie de ces paquetages. Généralement un ou les deux ci-après :
• javax.swing
• javax.swing.event (pas toujours requis)
• La classe JApplet : créer des applications (applets) qu'un navigateur Web peut télécharger sur le Net et exécuter.
• La classe JDialog permet de créer des boites de dialogue.
• La classe JFrame : utilisée pour créer des objets de type cadre ou fenêtre d'encadrement non contenue dans une autre fenêtre.
• La classe JComponent est la classe dont héritent tous les composants graphiques swing qui ne sont pas des fenêtres.
• La classe AbstractButton est la superclasse des objets de type bouton.
• La classe JButton permet de créer et gérer des objets de type bouton. Le package swing permet de créer des boutons plus évolués
qu'avec AWT (avec des images, ronds, etc.).
• La classe JCheckBox permet la gestion des cases à cocher.
• La classe JComboBox permet de gérer des listes déroulantes.
• La classe JLabel sert à créer des étiquettes.
• La classe JList permet de créer et gérer les zones de listes.
• La classe JMenu représente un menu qui peut être inséré sur une barre de menu.
• La classe JMenuBar permet de créer des barres de menu.
• La classe JMenuItem permet de créer les options des menus, les séparateurs et les sous-menus.
• La classe JradioButton : créer des boutons radio pour permettre aux utilisateurs de choisir une seule option parmi plusieurs.
• La classe JTextArea permet de créer des zones de saisie de texte de plusieurs lignes.
• La classe JTextComponent est une classe abstraite dont dérivent les zones de texte.
• La classe JTextField sert à gérer des zones de texte permettant la saisie d'une seule ligne.
• La classe JToggleButton est la superclasse dont héritent JCheckBox et JRadioButton.
return pane;
}
if (LOOKANDFEEL != null) {
if (LOOKANDFEEL.equals("Metal")) {
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
} else if (LOOKANDFEEL.equals("System")) {
lookAndFeel = UIManager.getSystemLookAndFeelClassName();
} else if (LOOKANDFEEL.equals("Motif")) {
lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
} else if (LOOKANDFEEL.equals("GTK+")) { //new in 1.4.2
lookAndFeel = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
} else {
System.err.println("Unexpected value of LOOKANDFEEL specified: "
+ LOOKANDFEEL);
lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
}
try {
UIManager.setLookAndFeel(lookAndFeel);
} catch (ClassNotFoundException e) {
System.err.println("Couldn't find class for specified look and feel:"
+ lookAndFeel);
System.err.println("Did you include the L&F library in the class path?");
System.err.println("Using the default look and feel.");
} catch (UnsupportedLookAndFeelException e) {
System.err.println("Can't use the specified look and feel ("
+ lookAndFeel
+ ") on this platform.");
System.err.println("Using the default look and feel.");
} catch (Exception e) {
System.err.println("Couldn't get specified look and feel ("
+ lookAndFeel
+ "), for some reason.");
System.err.println("Using the default look and feel.");
e.printStackTrace();
}
}
}
try
{
editeur = new JEditorPane(new URL("http://www.iutfv-bandjoun.info"));
editeur.setEditable(false);
editeur.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
URL url = e.getURL();
if (url == null)
return;
try {
editeur.setPage(e.getURL());
} catch (Exception ex) {
Malheureusment, le fait que SWT n'utilise pas de purs objets java, il n'est pas possible de compter sur le « ramasse
miettes » pour libérer la mémoire des composants créés manuellement. Pour libérer cette mémoire, il est nécessaire
d'utiliser la méthode dispose() pour les composants instanciés lorsque ceux ci ne sont plus utiles.
Il faut toutefois rester vigilant lors de l'utilisation de certains objets qui ne sont pas des contrôles, tels que les objets de type
Font ou Color, qu'il convient de libérer explicitement sous peine de « fuites de mémoire ».
N’oubliez pas qu’il faudrait éviter d’utiliser un objet dont la méthode dispose() a été appelée. Ceci entrainerait un résultat
imprévisible !
Voici la structure (étapes clés) d'une application graphique utilisant l’API SWT :
• création d'un objet de type Display qui assure le dialogue avec le système sous jacent,
• création d'un objet de type Shell qui est la fenêtre de l'application,
• création des composants et leur ajout dans le Shell,
• enregistrements des Listeners pour le traitement des événements,
• exécution de la boucle de gestion des événements jusqu'à la fin de l'application,
• libération des ressources de l'objet Display.
shell.open();
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
}
NB : Pour exécuter cet exemple sous windows, il faut que le fichier « swt.jar » correspondant à la plate-forme Windows soit inclus dans
le classpath et que l'application puisse accéder à la bibliothèque swt-win32-2135.dll
Evolution ?
Le concept de threads n'est pas vraiment récent. Avant Java, les threads n'étaient pas aussi connus que maintenant
parce qu'aucune « API » n'existait pour standardiser leur utilisation sur des plates-formes différentes. Java est fourni avec
une API de threads prise en charge par chaque JVM exécutée sur chaque plate-forme.
Le constructeur de threadComptage prend deux paramètres de type int pour initialiser ses propriétés start et finish . La
méthode run() identifie d'abord l'objet thread en cours en affichant son nom à l'écran. Ensuite, elle utilise une boucle for
pour effectuer le comptage entre start et finish, et elle affiche chaque nombre à l'écran. Avant de terminer, elle affiche un
message de fin d'exécution.
threadComptage peut être utilisé dans une application de la façon suivante:
public class threadTester
{
static public void main(String[] args)
{
threadComptage thread1 = new threadComptage (1, 10);
threadComptage thread2 = new threadComptage (20, 30);
thread1.start();
thread2.start();
}
}
La méthode main() ci-dessus crée deux objets threadComptage : thread1 compte de 1 à 10 ; thread2 compte de 20 à 30 .
Elle démarre ensuite les deux threads en appelant leurs méthodes start() . Quand cette méthode main() est exécutée dans
une application, le résultat ressemble à ceci:
Thread-1 début d'exécution...
Thread-2 début d'exécution...
20 21 22 23 24 25 26 27 28 29 30 Thread-2 fin d'exécution.
Pour créer threadComptage2 , utilisez l'interface Runnable au lieu de créer une sous-classe de la classe Thread; il suffit de
modifier sa déclaration selon l'exemple ci-dessous:
public class threadComptage2 implements Runnable {
//la suite n'est pas modifiée
}
Bien que l'implémentation de la classe threadComptage2 n'ait besoin d'aucune modification pour implémenter Runnable, la
façon de créer ses objets doit être modifiée. Au lieu d'instancier threadComptage, comme nous l'avons fait auparavant, il
faut créer un objet Runnable à partir de threadComptage2 et le transmettre à un des constructeurs de threads. Voici
comment créer l'objet thread1 selon cette méthode:
Runnable rThread = new threadComptage2(1, 10);
Thread thread1 = new Thread(rThread);
Etudions maintenant pourquoi nous avons travaillé ainsi. threadComptage est une sous-classe de la classe Thread; elle
hérite par conséquent du comportement d'un thread Java. Cela signifie que vous disposez dans un objet de threadComptage
de toutes les fonctionnalités prises en charge par la classe Thread, comme appeler start(). Cependant, threadComptage2
n'hérite en rien de la classe Thread et ne prend donc pas en charge le comportement de la classe Thread. threadComptage2
n'a fait que définir la méthode run(), qui peut être appelée quand un objet threadComptage2 est exécuté dans un thread.
La méthode sleep()
Pour mettre un thread au repos, utilisez une des deux méthodes suivantes :
public static void sleep(long milliseconde)
public static void sleep(long milliseconde, int nanoseconde)
Par exemple, pour qu'un thread s'arrête pendant une seconde, appelez sleep(1000) sur le thread.
La méthode yield()
Dans certains cas, de nombreux threads sont en attente de la fin de l'exécution du thread en cours avant de pouvoir
s'exécuter. Pour que le programmateur de threads bascule l'exécution sur les autres threads, appelez la méthode yield() sur
le thread en cours. Pour que yield() fonctionne, il doit y avoir au moins un thread de priorité égale ou supérieure au thread
actuel.
La méthode join()
public final void join()
public final void join(long millisecond)
Pour qu'un deuxième thread attende la fin d'exécution d'un premier thread, appelez la méthode join() sur le premier thread.
Vous pouvez préciser un délai à l'aide d'un paramètre de temps donné en millisecondes. join() attend jusqu'à la fin du délai
ou jusqu'à la fin de l'exécution du premier thread. Pour savoir si un thread s'est terminé, join() utilise la méthode isAlive().
Si isAlive() renvoie true, join() n'est pas renvoyée et continue à attendre que le premier thread se termine. Si isAlive()
renvoie false, join() est renvoyée et le deuxième thread peut s'exécuter.
Cette classe déclare une méthode swap() qui intervertit les valeurs de ses deux propriétés, from et to. La méthode prend la
propriété from, la stocke dans une variable temp, puis stocke la valeur de to dans from et la valeur de temp dans to.
Envisageons le cas où deux méthodes différentes démarrent leurs propres threads pour exécuter swap() simultanément -
appelons-les thread1 et thread2. Par hypothèse, le thread1exécute la méthode en premier et, au moment de l'exécution, from
a la valeur 5 et to la valeur 6. thread1 exécute la première ligne de code et donne à temp la valeur 5. A la fin de la deuxième
ligne, from reçoit la valeur 6. A ce moment, thread2 démarre l'exécution de la méthode. Pour thread2, from a la valeur 6
(attribuée par thread1) et to a aussi la valeur 6. thread2 exécute la totalité de la méthode et intervertit les valeurs 6 et 6. Une
fois thread2 terminé, thread1 reprend son exécution à la troisième ligne et attribue à to la valeur de temp (maintenant 6). A
la fin de thread1, from et to ont la valeur 6;
L'opération attendue (intervertir 5 et 6) n'a jamais eu lieu!
Pour éviter ce scénario, il suffit d'ajouter le mot clé synchronized à la signature de swap(), comme ceci:
public synchronized void swap()
Maintenant, un seul thread peut exécuter swap() à un moment donné. Dans ce cas, thread1 exécute la totalité de la méthode
et intervertit correctement les valeurs de from et de to. Une fois thread1 terminé, thread2 exécute swap() et intervertit une
nouvelle fois les valeurs.
Comme règle de base: toute méthode qui modifie des propriétés d'objets devrait être déclarée synchronized.
4.9.4.2 Moniteurs
Un environnement qui prend en charge plusieurs threads doit implémenter quelques techniques de contrôle de la
simultanéité. Il en existe plusieurs, comme les sémaphores, les sections critiques et le verrouillage (exemple des
enregistrements de BD). Java implémente un mécanisme de contrôle de la simultanéité appelé moniteur.
Traditionnellement, un moniteur est un objet, qui contrôle quelque chose, comme une procédure. Le travail du moniteur
consiste à vérifier qu'un seul thread à la fois peut exécuter la procédure qu'il contrôle. Dans Java, chaque objet dispose d'un
moniteur associé. Le moniteur s'assure qu'un seul thread à la fois exécute les méthodes synchronized appartenant à l'objet
qu'il contrôle. Le moniteur interdit à tout autre thread d'exécuter la même méthode synchronized tant que le thread en cours
d'exécution n'est pas terminé. Si aucun thread n'exécute la méthode cible synchronized, un thread peut entrer dans le
moniteur (ou verrouiller le moniteur pour lui-même). A partir de ce moment, aucun autre thread ne peut exécuter la
méthode tant que le thread actuel ne quitte pas le moniteur.
Les moniteurs Java ne sont pas des objets réels, car ils n'ont ni méthode ni propriété. Ils sont intégrés à l'implémentation
multithread de Java et restent invisibles au programmeur. Ainsi, notre présentation de moniteurs restera conceptuelle.
class ThreadSwing
{
public static void main(String args[])
{
System.out.println("main -----> thread name = "
+ Thread.currentThread().getName());
JFrame frame = new JFrame("ThreadSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton bouton = new JButton("Afficher");
frame.getContentPane().add(bouton);
bouton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("actionPerformed -----> thread name = "
+ Thread.currentThread().getName());
infoAllThread();
}
});
frame.pack();
frame.setVisible(true);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {}
}
public static void infoThread(Thread thread, String indent) {
if (thread == null)
System.out.println(indent + "Thread null !!");
else
System.out.println(indent + "Thread : name=" + thread.getName() +
" priority=" + thread.getPriority() +
" daemon=" + thread.isDaemon() +
" alive=" + thread.isAlive());
}
public static void infoThreadGroup(ThreadGroup tGroup) {
infoThreadGroup(tGroup, "");
}
public static void infoThreadGroup(ThreadGroup tGroup, String indent)
{
if (tGroup == null)
System.out.println(indent + "GroupThread null !");
else {
System.out.println(indent + "ThreadGroup" +
" name:" + tGroup.getName() +
" priority_max=" + tGroup.getMaxPriority() +
" daemon=" + tGroup.isDaemon());
int nbreThreadFils = tGroup.activeCount();
System.out.println(indent + "nbreThreadFils="+nbreThreadFils);
Thread[] threadFils = new Thread[nbreThreadFils];
tGroup.enumerate(threadFils,false);
for (int i = 0; i < nbreThreadFils; i++)
infoThread(threadFils[i], indent + " ");
int nbreGroupFils = tGroup.activeGroupCount();
System.out.println(indent + "nbreGroupFils="+nbreGroupFils);
ThreadGroup[] tGroupFils = new ThreadGroup[nbreGroupFils];
tGroup.enumerate(tGroupFils,false);
for (int i = 0; i < nbreGroupFils; i++)
infoThreadGroup(tGroupFils[i],indent + " ");
}
}
4.10 LA SERIALISATION
4.10.1 GENERALITES
La sérialisation d'un objet est le processus de stockage d'un objet complet sur disque ou tout autre système de
stockage, d'où il pourra être restauré à tout moment. Le processus inverse de la restauration est connu sous le nom de
désérialisation. Dans cette section, nous allons voir l'utilité de la sérialisation et la façon dont Java implémente la
sérialisation et la désérialisation.
Un objet sérialisé est dit « persistant ». Par contraste, la plupart des objets en mémoire sont « transiants », ce qui signifie
qu'ils s'en vont quand leurs références sortent de la portée ou quand l'ordinateur est éteint. Les objets « persistants », quant
à eux, existent tant qu'il reste une copie stockée quelque part sur disque, bande ou CD-ROM.
Pourquoi sérialiser ?
Traditionnellement, enregistrer des données sur disque ou une autre unité de stockage nécessite la définition d'un
format de données spécial, l'écriture de fonctions de lecture et d'écriture pour ce format et la création d'une « mappe » entre
le format du fichier et le format des données. Les fonctions de lecture et d'écriture des données étaient soit simples et sans
possibilité d'extension soit complexes et difficiles à créer et à maintenir.
Comme vous devez le savoir maintenant, Java est totalement basé sur les objets et la programmation orientée objet. Pour
cela, le langage fournit un mécanisme de stockage des objets, appelé sérialisation. Avec la façon de faire de Java, vous
n'avez plus besoin de vous préoccuper des détails concernant les formats des fichiers et les E/S. La conception et
l'implémentation d'objets permet de consacrer plus de temps à la résolution des tâches du monde réel. Si, par exemple, vous
rendez une classe persistante et y ajoutez de nouveaux champs par la suite, vous n'avez pas à vous préoccuper de la
modification des programmes de lecture et d'écriture des données.
Tous les champs qui se trouvent dans un objet sérialisé sont automatiquement écrits et restaurés.
4.10.2 SERIALISATION
La sérialisation est une fonction qui date du JDK 1.1. La prise en charge de la sérialisation par Java se compose de
l'interface Serializable, des classes ObjectOutputStream et ObjectInputStream, ainsi que de quelques classes et
interfaces de support. Nous allons illustrer ces trois éléments par une application qui enregistre sur disque des informations
sur les utilisateurs et les relit.
Par exemple, supposons que vous vouliez enregistrer des informations sur un utilisateur particulier comme illustré ci-
dessous. Une fois que l'utilisateur a tapé son nom et son mot de passe dans les champs appropriés, l'application doit
enregistrer ces informations sur disque. Naturellement, cet exemple est très simple, mais il est applicable à l'enregistrement
de données sur les préférences des utilisateurs relatives à leurs applications, du dernier document ouvert, etc.
Remarquez que la classe ci-dessus implémente l'interface java.io.Serializable. Serializable est connue sous le nom
"d'interface de balisage", puisqu'elle ne spécifie aucune méthode à implémenter, mais "balise" plutôt ses objets comme
étant d'un type particulier.
Tout objet prévu pour être sérialisé doit implémenter cette interface. Cela est important, car, sinon, les techniques utilisées
dans la suite ne fonctionnent pas. Si, par exemple, vous essayez de sérialiser un objet qui n'implémente pas cette interface,
une NotSerializableException est émise.
Méthodes ObjectOutputStream
La classe ObjectOutputStream contient plusieurs méthodes utiles pour mettre des données dans un flux. Vous
n'êtes pas limité aux objets d'écriture. Appeler writeInt(), writeFloat(), writeDouble() écrira dans un flux n'importe quel
type fondamental. Pour écrire plusieurs objets ou types fondamentaux dans le même flux, appelez ces méthodes plusieurs
fois sur le même objet ObjectOutputStream. Cependant, attention, relire les objets dans le même ordre.
Application JDBC
Java
Gestionnaire de Pilote
Protocole
spécifique
Application /
Serveur (HTTP, RMI, CORBA)
Applet
Java
HTTP
RMI JDBC
CORBA
... Gestionnaire de Pilote
Protocole
spécifique
Utilisation du pilote : Le pilote peut être téléchargé sous forme d’archive sur Internet. Pour utiliser cette archive, il faut la
décompresser, par exemple dans le répertoire d'installation de votre SGBD.
Il faut s'assurer que les fichiers jar sont accessibles dans le classpath ou les préciser manuellement lors de la compilation.
Ceci évitera de repréciser à chaque fois (durant la compilation) le chemin complet du pilote ;
Voir exemple ci-dessous (le classpath n’ayant pas été défini) :
C:\$user>javac -classpath c:\j2sdk1.8.0-rc\jre\lib\postgresql.jdbc4.jar TestJDBC11.java
C:\$user>java -cp .;c:\j2sdk1.8.0-rc\jre\lib\postgresql.jdbc4.jar TestJDBC11
//-----------------------------------------------------------------------
La classe ResultSet
Cette classe représente une abstraction d'une table qui se compose de plusieurs enregistrements constitués de colonnes qui
contiennent les données.
Les principales méthodes pour obtenir des données sont :
Méthode Role
getInt(int) retourne le contenu de la colonne dont le numéro est passé en paramètre sous forme d'entier.
getInt(String) retourne le contenu de la colonne dont le nom est passé en paramètre sous forme d'entier.
getFloat(int) retourne le contenu de la colonne dont le numéro est passé en paramètre sous forme de nombre flottant.
getFloat(String)
getDate(int) retourne le contenu de la colonne dont le numéro est passé en paramètre sous forme de date.
getDate(String)
next() se déplace sur le prochain enregistrement : retourne false si la fin est atteinte
Close() ferme le ResultSet
getMetaData() retourne un objet ResultSetMetaData associé au ResultSet.
La méthode getMetaData() retourne un objet de la classe ResultSetMetaData qui permet d'obtenir des informations
sur le résultat de la requête. Ainsi, le nombre de colonnes peut être obtenu grace à la méthode getColumnCount de cet objet.
Nous allons dans un exemple, récupérer les données d’une table « Produit » dans une Base de données « Commerce ».
import java.sql.*;
// chargement du pilote
try {
Class.forName("org.postgresql.Driver").newInstance();
} catch (Exception e) {
arret("Impossible de charger le pilote jdbc pour PostgreSQL");
}
try {
Statement ObjetReq = ConnPsql.createStatement();
resultats = ObjetReq.executeQuery(requete);
} catch (SQLException e) {
arret("Anomalie lors de l'execution de la requete");
}
while (suivant) {
System.out.println();
suivant = resultats.next();
}
resultats.close();
} catch (SQLException e) {
arret(e.getMessage());
}
5.1 INTRODUCTION
JAVA est un langage de programmation par excellence des applications réseau et client-serveur, notamment autour du
Worl Wide Web.
Les Bibliothèques réseau Java sont suffisament fournies pour pouvoir lire et écrire des flux d’informations et éffectuer des
traitements répartis entre machines en réseau.
5.3 SERVLETS
5.10 CONCLUSION
6.1 INTRODUCTION
Il est question dans ce chapitre de faire une brève introduction sur les concepts, techniques et outils
complémentaires, pour ouvrir l’esprit des apprenants qui auront à affronter des projets tout au long de leur carrière.
Présentation de JNI
Il est possible :
• D’appeler des fonctions C/C++ depuis Java.
• D’accéder à des objets Java depuis le C/C++.
En plus, JNI permet :
• D’écrire des méthodes natives
• D’appeler des méthodes java
• De capturer et de déclencher des exceptions
• De charger des classes
• etc.
Lorsqu’on combine les profiles MIDP (Mobile Information Device Profile) et CLDC (Connected Limited Device
Configuration), on a un environnement d’exécution Java de référence, très adapté aux équipements compactes et mobiles
tesl que les téléphones cellulaires, les PDAs, etc.
MIDP était le premier profile développé, dont l'objectif principal était le développement d'application sur des machines aux
ressources et interface limitées tel qu'un téléphone cellulaire. Ce profil peut aussi être utilisé pour développer des
applications sur des PDA de type Palm.
L'API du MIDP se compose des API du CDLC et de trois packages :
• javax.microedition.midlet : cycle de vie de l'application ;
6.6.4 CONCLUSION
[WWWJME06]
La fusion PDA, téléphone, console de jeux, lecteur mp3 se fait. Les débits de communications augmentent et les
applications logicielles deviennent vraiment communiquantes et les accès aux bases de données, à divers serveurs ouvrirent
encore plus les possibilités des développeurs. Avec MIDP, les développeurs peuvent déjà toucher un bon nombre d'usagers.
Au fur et à mesure, les avancées technologiques importantes toucheront le grand public et on y a déjà remarqué
l'importance de la téléphonie.
En plus des SDK propriétaires à chaque constructeur, d'autres technologies essayent de s'insérer dans ce marché. On
trouve, par exemple, un framework .NET dépouillé même si peu des téléphones actuels l'utilisent (plutôt reservé aux PDA
de type PocketPC) ... Macromedia propose dans son Flash MX de créer des applications pour les appareils mobiles, un
FlashPlayer allégé existe aussi.
* Problem: I recompiled my applet, but my applet viewing application won't show the new version, even though I told it to reload
it.
•In many applet viewers (including browsers), reloading isn't reliable. This is why we recommend that you simply use the JDK Applet
Viewer, invoking it anew every time you change the applet. •If you get an old version of the applet, no matter what you do, make sure
that you don't have an old copy of the applet in a directory in your CLASSPATH. See Managing Source and Class Files<Image: (in the
Learning the Java Language trail)> for information about the CLASSPATH environment variable.
* Problem: The light gray background of my applet causes the applet to flicker when it's drawn on a page of a different color.
•You need to set the background color of the applet so that it works well with the page color. See Creating a GUI<Image: (in the Writing
Applets trail)> for details.
* Problem: The Applet getImage method doesn't work.
•Make sure you're calling getImage from the init method or a method that's called after init. The getImage method does not work when
it's called from a constructor.
* Problem: Now that I've copied my applet's class file onto my HTTP server, the applet doesn't work.
•Does you applet define more than one class? If so, make sure that the class file (ClassName.class) for each class is on the HTTP server.
Even if all the classes are defined in one source file, the compiler produces one class file per class. •Did you copy all the data files for
your applet -- image and sound files, for example -- to the server? •Make sure all the applet's class and data files can be read by everyone.
•Make sure the applet's class and data files weren't garbled during the transfer. One common source of trouble is using the ASCII mode
of FTP (rather than the BINARY mode) to transfer files.
* Problem: I can't get my applet to run. The browser displays a ClassCastException.
•If your applet has multiple classes, did you specify the right one (an Applet subclass) in the applet tag's CODE attribute?
Note: All component sizes are subject to layout manager approval. The FlowLayout and GridBagLayout layout managers use the
component's natural size (the latter depending on the constraints that you set), but BorderLayout and GridLayout usually don't. Other
options are writing or finding a custom layout manager or using absolute positioning.
* Problem: How do I resize a component?
•Once a component has been displayed, you can change its size using the Component setSize method. You then need to call the validate
method on the component's container to make sure the container is laid out again.
* Problem: My custom component is being sized too small.
•Does the component implement the getPreferredSize and getMinimumSize methods? If so, do they return the right values? •Are you
using a layout manager that can use as much space as is available? See General Rules for Using Layout Managers for some tips on
choosing a layout manager and specifying that it use the maximum available space for a particular component.
Ouvrages
• [RoquesVallee01] Pascal Roques & Franck Vallée, « UML en action: de l’analyse des besoins à la conception en Java », Edition
Eyrolles, Paris, 3ème tirage, 2001, 385 pages, ISBN: 2-212-09127-3
• [Fowler03] Martin FOWLER, UML Distilled: A Brief Guide to the Standard Object Modeling Language, Paperback: 192
pages, Publisher: Addison-Wesley Professional; 3 edition (September 19, 2003), Language: English, ISBN:
0321193687
http://martinfowler.com/books.html#uml
• [Warmer99] J. Warmer, A. Kleppe, “The Object Constraint Language: Precise Modeling with UML”, Addison-Wesley,
1999.
• [Booch 88] Grady Booch. « Ingenierie du logiciel avec le langage ADA. » inter Edition 1988.
• [Booch91] Grady Booch,"Object oriented design with application." The benjamin/commings publishing company Inc ,
1991
• [Bouzegoub94] Bouzegoub M. "The functional Query language Morse." Proc of Trends & Application on Databases, IEE,
Gaithersburg, MD, USA 1984
• [Bouzegoub97] Mokrane BOUZEGOUB, Georges GARDARIN, Patrick VALDURIEZ. "Les Objets" édition Eyrolles 1997.
• [Coad91a] Coad P., Yourdon E. "Object oriented analysis, second edition" Yourdon Press, Prentice-Hall, Inc. 1991
• [Coad91b] Coad P., Yourdon E. "Object oriented Design" Yourdon Press, Prentice-Hall, Inc. 1991
• [Coleman94] Coleman D., Arnold P., Bodoff S. "Object oriented Development: The FUSION method" Prentice-Hall,
Englewood cliffs, NJ,1994
• [Delannoy 01] Claude DELANNOY, « Programmer en Java », Eyrolles, 2001.
• [Delatte93] Delatte B., Heitz M., Muller J.F. "HOOD reference manual 3." Edition Masson 1993.
• [Dorseuil 95] A.DORSEUIL & P.PILLOT. « Le temps réel en milieu industriel: concepts, environnements, multitâches.»
Edition Dunod 1995
• [Gardarin97] Goerges et Olivier GARDARIN. "Le Client-Serveur", édition Eyrolles 1997.
• [Gaudel96] Marie Claude GAUDEL, Bruno MARRE, Françoise SCHLIENGER, Gilles BERNOT. "Précis de Génie
logiciel" Edition Masson 1996.
• [Hirsh 90] ERNEST HIRSH. « Les Transputers. » edition Eyrolles 1990.
• [Jacobson 92] Jacobson I., Christerson M., Jonson P., Övergaard G. "Object oriented software engeneering: A use case driven
approach" Addison-wesley, 1992
• [Leray92] J. LERAY. "Les bases de l'informatique industrielle" Dunod 1992
• [Manhes98] Stéphane MANHES, B. DANO. « La réutilisabilité : Patterns et Frameworks » rapprot complet : « les
patterns métiers : extraction dans l’existant logiciel » rapport de DEA, IRIN, Université de Nantes, sept 1998
• [Nkenlif 99] Marcellin NKENLIFACK, «Spécifications orientées objets de circuits électroniques » Mémoire de fin de 1ère
année doctorat, ENSP, Université de Yaoundé I, Cameroun. 1999.
• [Raise92] The RAISE Language Group "The RAISE Specification Language" . Prentice-Hall International 1992
• [Raise95] The RAISE Method Group "The RAISE Development Method" . Prentice-Hall International 1995
• [Rumbaugh91] Rumbaugh J., Blaha M., Premerlani W., Eddy F. "Object oriented modeling and design." Prentice Hall
International, 1991.
• [Shlaer92] Shlaer S., Mellor S.J. "Object life cycle: Modeling the world in state" Yourdon Press, Prentice-Hall, 1998
Articles
• [Ashenden99] Peter J. ASHENDEN (The university of Adélaïde), «The overview of SUAVE language feature » FDL 1999,
Lyon, France.
• [AshRad99] Peter J. ASHENDEN (The university of Adélaïde), Martin RADETZKI (Oldenburg University). «A
comparison of SUAVE and Objective VHDL » Report for the IEEE-DASC-OOVHDL study group. FDL 1999,
Lyon, France.
• [Nebel98] Wolfgang NEBEL, Martin RADETZKI, Wolfram PUTZKE. « Reuse and Quality estimation : Objective
VHDL language definition » REQUEST/OFFI/D2.1A/01.2. – 09/07/1998
• [Nebel99] Wolfgang NEBEL, Martin RADETZKI, Wolfram PUTZKE. « Reuse and Quality estimation : Demo release
Objective VHDL User’s Manual » REQUEST/OFFI/DEMO/01.1 – 18/01/1999.
• [Otter-H4028] Martine OTTER, « Qualité des logiciel.» article paru dans les techniques de l’ingénieur, Doc H4028
• [Printz-H3208] Jacques PRINTZ, « Génie logiciel » article paru dans les techniques de l’ingénieur, Doc H3208
• [Rollan-H3248] Colette ROLLAND «Conception de bases de données: une méthode orientée objet et événement» article paru
dans les techniques de l’ingénieur, Doc H3248