Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
1 Introduction
Java est un langage de programmation récent (les premières versions datent de 1995) développé
par Sun Microsystems. Il est fortement inspiré des langages C et C++. Comme C++, Java fait
partie de la « grande famille » des langages orientés objets. Il répond donc aux trois principes
fondamentaux de l’approche orientée objet (POO) : l’encapsulation, le polymorphisme et
l’héritage.
- C'est un langage orienté objet dérivé du C, mais plus simple à utiliser et plus « pur » que le
C++. On entend par « pur » le fait qu’en Java, on ne peut faire que de la programmation
orienté objet contrairement au C++ qui reste un langage hybride, c’est-à-dire autorisant
plusieurs styles de programmation. C++ est hybride pour assurer une compatibilité avec le
C;
- Il est doté, en standard, de bibliothèques de classes très riches comprenant la gestion des
interfaces graphiques (fenêtres, boites de dialogue, contrôles, menus, graphisme), la
programmation multi-threads (multitâches), la gestion des exceptions, les accès aux fichiers
et au réseau … L’utilisation de ces bibliothèques facilitent grandement la tâche du
programmeur lors de la construction d’applications complexes ;
1
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
- Il est doté, en standard, d’un mécanisme de gestions des erreurs (les exceptions) très utile
et très performant. Ce mécanisme, inexistant en C, existe en C++ sous la forme d’une
extension au langage beaucoup moins simple à utiliser qu’en Java ;
- Il est multi plates-formes : les programmes tournent sans modification sur tous les
environnements où Java existe (Windows, Unix et Mac) ;
Remarque :
Ce dernier point a contribué à utiliser d'abord Java pour développer des applets qui sont des
applications pouvant être téléchargées via l’Internet et exécutées dans un navigateur sur
n'importe quelle plate-forme. Ainsi, une page statique HTML peut s'enrichir de programmes
qui lui donneront un comportement dynamique.
Avec les langages évolués courant (C++, C, etc.) nous avons pris l’habitude de coder sur une
machine identique à celle qui exécutera nos applications ; la raison est fort simple : à de rares
exceptions près les compilateurs ne sont pas multi-plateformes et le code généré est spécifique
à la machine qui doit accueillir. Nous devons alors utiliser n compilateurs différents sur n
machines. Aujourd’hui, la généralisation des interfaces graphiques et l’usage de langage plus
évolués compliquent encore d’avantage le problème. Ainsi pour développer une application
destinée à plusieurs systèmes d’exploitation avec ses différentes couches de librairies et
d’interfaces ; les API de ces interfaces étant toutes différentes. Ainsi nos applications sont
fortement dépendantes des ressources (y compris graphique) du système hôte, dépendantes des
API des interfaces utilisées, et le code produit ne peut s’exécuter que sur le système pour lequel
il a été initialement produit.
Tout d’abord, Java simplifie le processus de développement : quelle que soit la machine sur
laquelle on code, le compilateur fournit le même code. Ensuite, quel que soit le système utilisé
cet unique code est directement opérationnel : En effet, la compilation d’un source Java produit
2
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
du pseudo-code (byte code) Java qui sera exécuté par tout interpréteur Java sans aucune
modification ou recompilation. Cet « interpréteur » est couramment dénommé « machine
virtuelle Java ».
2.3 Conséquences :
- Java est donc un langage qui doit être compilé et interprété. Dans une première phase on
compile un programme (un ou plusieurs fichiers source .java) en fichiers.class. Le
compilateur génère un fichier .class pour chacune des classes définies dans le(s) fichier(s)
.java. L'ensemble des fichiers .class est ensuite interprété par la Machine Virtuelle Java
(Java Virtual Machine) pour exécuter le programme (seule la JVM dépend du système). Ce
principe donne à Java une portabilité maximale (Windows, Unix, Macintosh …). Les
figures ci-dessous montrent la différence de principe entre la compilation dans un langage
classique (C++) et la compilation/interprétation en Java.
3
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
- Les fichiers .class contiennent du bytecode, une sorte de code machine Java (comparable
au code machine d'un microprocesseur). L'interpréteur exécute beaucoup plus rapidement
ce bytecode que les fichiers sources .java.
- Seuls les fichiers .class sont nécessaires à l'exécution d'un programme Java. Ils contiennent
du code machine et ne peuvent donc pas être lus par des tiers, protégeant ainsi le code
source.
- Etant compilés, les fichiers .class sont de taille plus petite que le code source Java ; ceci est
un argument important pour transférer les programmes sur l’Internet.
- Chaque fichier .class décrivant une classe d'objet, une même classe peut être utilisée par
Différents programmes sans que cette classe ne soit dupliquée dans chacun des
programmes.
- Un exécutable contient du code qui n'est exécutable que sur la machine pour laquelle il est
destiné et le seul moyen de rendre un langage multi plates-formes, sans avoir à recompiler
le code source (comme en C/C++), est d'utiliser un interpréteur. L'autre avantage de
l'interpréteur est qu'il peut être incorporé à un navigateur (Netscape/Internet Explorer), ce
qui lui permet d'exécuter des programmes Java à l'intérieur de pages HTML.
- L’interpréteur prend forcément un certain temps pour interpréter le code des fichiers .class,
ce qui rend les programmes moins rapides que de « vrais exécutables ». Mais Java est encore
jeune et Sun Microsystems et d'autres éditeurs de logiciels tentent d'optimiser les Machines
Virtuelles Java. L'un des axes d'optimisation est actuellement le développement de
compilateurs JIT (Just In Time) : quand une classe est chargée, elle est traduite dans le code
machine de la plate-forme où elle est exécutée. Cette opération ralentit le départ de
l'application, mais l'exécution du programme est ensuite beaucoup plus rapide !
4
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
Téléchargement : http://www.sun.com/products/index.html
Configuration :
La variable d’environnement ‘path’ indique à Windows le chemin d’accès qu’il doit utiliser
pour trouver les programmes exécutables. Windows cherche les programmes exécutables tout
d’abord dans le dossier à partir duquel la commande est tapée, puis dans les dossiers dont les
chemins d’accès sont indiqués par la variable « path ».
5
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
En Résumé :
Contrairement au C/C++, le compilateur Java ne génère pas de fichier exécutable. Il crée pour
chacune des classes d'un fichier Java un fichier .class qui sera interprété par la Machine
Virtuelle Java.
- Compilation : javac [<options>] <fichiers-source- « .java »> . Exemple : javac Test.java
4.1 L’encapsulation
6
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
Notion d’objet :
La difficulté de cette modélisation consiste à créer une représentation abstraite, sous forme
d'objets, d'entités ayant une existence matérielle (chien, voiture, ampoule, ...) ou bien virtuelle
(sécurité sociale, temps, ...).
Les attributs : Il s'agit des données caractérisant l'objet. Ce sont des variables stockant
des informations d'état de l'objet
Les méthodes (appelées parfois fonctions membres): Les méthodes d'un objet
caractérisent son comportement, c'est-à-dire l'ensemble des actions (appelées
opérations) que l'objet est à même de réaliser. Ces opérations permettent de faire réagir
l'objet aux sollicitations extérieures (ou d'agir sur les autres objets). De plus, les
opérations sont étroitement liées aux attributs, car leurs actions peuvent dépendre des
valeurs des attributs, ou bien les modifier
L’identité : L'objet possède une identité, qui permet de le distinguer des autres objets,
indépendamment de son état. On construit généralement cette identité grâce à un
identifiant découlant naturellement du problème (par exemple un produit pourra être
repéré par un code, une voiture par un numéro de série, etc.)
Notion de classe :
On appelle classe la structure d'un objet, c'est-à-dire la déclaration de l'ensemble des entités qui
composeront un objet. Un objet est donc « issu » d'une classe, c'est le produit qui sort d'un
7
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
moule. En réalité on dit qu'un objet est une instanciation d'une classe, c'est la raison pour
laquelle on pourra parler indifféremment d'objet ou d'instance (éventuellement d'occurrence).
Les attributs (parfois appelés données membres) : il s'agit des données représentant
l'état de l'objet.
Les méthodes (parfois appelées fonctions membres): il s'agit des opérations applicables
aux objets
Si on définit la classe voiture, les objets Peugeot 406, Renault 18 seront des instanciations de
cette classe. Il pourra éventuellement exister plusieurs objets Peugeot 406, différenciés par leur
numéro de série.
Deux instanciations de classes pourront avoir tous leurs attributs égaux sans pour autant être un
seul et même objet.
Il faut pouvoir lui demander d'exécuter une requête, telle que terminer une transaction, dessiner
quelque chose à l'écran, ou allumer un interrupteur. Chaque objet ne peut traiter que certaines
requêtes. Les requêtes qu'un objet est capable de traiter sont définies par son interface et son
type est ce qui détermine son interface.
8
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
L'interface précise quelles sont les caractéristiques d’un objet (ici type et puissance) et quelles
sont les opérations que l’on peut effectuer sur un objet particulier (ici Allumer et Eteindre).
L’interface ne précise pas la manière dont elles sont effectuées (c’est-à-dire le code
correspondant à l’opération) : c’est le rôle de l’implémentation.
L'encapsulation est donc un mécanisme consistant à rassembler les données et les méthodes au
sein d'une structure en cachant l'implémentation de l'objet, c'est-à-dire en empêchant l'accès aux
données par un autre moyen que les services proposés. L'encapsulation permet donc de garantir
l'intégrité des données contenues dans l'objet.
L'utilisateur d'une classe n'a pas forcément à savoir de quelle façon sont structurées les données
dans l'objet, cela signifie qu'un utilisateur n'a pas à connaître l'implémentation. Ainsi, en
interdisant l'utilisateur de modifier directement les attributs, et en l'obligeant à utiliser les
fonctions définies pour les modifier (appelées interfaces), on est capable de s'assurer de
l'intégrité des données (on pourra par exemple s'assurer que le type des données fournies est
conforme à nos attentes, ou encore que les données se trouvent bien dans l'intervalle attendu).
L'encapsulation permet de définir des niveaux de visibilité des éléments de la classe. Ces
niveaux de visibilité définissent les droits d'accès aux données selon que l'on y accède par une
méthode de la classe elle-même, d'une classe héritière, ou bien d'une classe quelconque. Il existe
trois niveaux de visibilité :
Publique : les fonctions de toutes les classes peuvent accéder aux données ou aux méthodes
d'une classe définie avec le niveau de visibilité public. Il s'agit du plus bas niveau de protection
des données
9
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
Protégée : l'accès aux données est réservé aux fonctions des classes héritières, c'est-à-dire par
les fonctions membres de la classe ainsi que des classes dérivées
Privée : l'accès aux données est limité aux méthodes de la classe elle-même. Il s'agit du niveau
de protection des données le plus élevé
La réutilisation des classe créées et testées est l’un des grands avantages des langages orientés
objets. Cependant créer des classes réutilisables demandent beaucoup de méthode et
d’expérience. La manière la plus simple de réutiliser une classe est d'utiliser directement un
objet de cette classe. On peut également placer un objet d’une classe à l'intérieur d'une nouvelle
classe : c’est ce qu’on appelle « créer un objet membre ».
Par exemple : « une voiture possède un moteur ».
10
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
4.2 L’héritage
Les objets, comme les données, possèdent un type que l’on appelle classe. Les classes peuvent
être organisées en hiérarchies, chaque classe héritant de sa classe mère ou super-classe.
L’héritage est ainsi source d’économie de code, une classe peut être définie comme la
descendante d’une classe (ou sous-classe).
L'héritage est donc un principe propre à la programmation orientée objet, permettant de créer
une nouvelle classe à partir d'une classe existante. Le nom d'héritage" (pouvant parfois être
appelé dérivation de classe) provient du fait que la classe dérivée (la classe nouvellement créée)
contient les attributs et les méthodes de sa superclasse (la classe dont elle dérive). L'intérêt
majeur de l'héritage est de pouvoir définir de nouveaux attributs et de nouvelles méthodes pour
la classe dérivée, qui viennent s'ajouter à ceux et celles héritées. Par ce moyen on crée une
hiérarchie de classes de plus en plus spécialisées. Cela a comme avantage majeur de ne pas
avoir à repartir de zéro lorsque l'on veut spécialiser une classe existante. De cette manière il est
possible d'acheter dans le commerce des librairies de classes, qui constituent une base, pouvant
être spécialisées à loisir (on comprend encore un peu mieux l'intérêt pour l'entreprise qui vend
les classes de protéger les données membres grâce à l'encapsulation...).
Exemple :
11
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
4.3 Le polymorphisme
Le nom de polymorphisme vient du grec et signifie qui peut prendre plusieurs formes. Alors
que l'héritage concerne les classes (et leur hiérarchie), le polymorphisme est relatif aux
méthodes des objets.
Le polymorphisme ad hoc :
Le polymorphisme ad hoc permet d'avoir des fonctions de même nom, avec des fonctionnalités
similaires, dans des classes sans aucun rapport entre elles (si ce n'est bien sûr d'être des filles
de la classe objet). Par exemple, la classe complexe, la classe image et la classe lien peuvent
avoir chacune une fonction "afficher". Le polymorphisme ad hoc permet ainsi de définir des
opérateurs dont l'utilisation sera différente selon le type des paramètres qui leur sont passés.
Le polymorphisme paramétrique :
Ainsi, on peut par exemple définir plusieurs méthodes homonymes addition() effectuant une
somme de valeurs.
12
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020
Le polymorphisme d'héritage :
La possibilité de redéfinir une méthode dans des classes héritant d'une classe de base s'appelle
la spécialisation. Il est alors possible d'appeler la méthode d'un objet sans se soucier de son type
intrinsèque : il s'agit du polymorphisme d'héritage. Ceci permet de faire abstraction des détails
des classes spécialisées d'une famille d'objet, en les masquant par une interface commune (qui
est la classe de base).
Exemple :
Dans le diagramme suivant, l'objet Contrôleur d'oiseaux travaille seulement avec des objets
Oiseaux génériques, et ne sait pas de quelle classe ils proviennent. C’est pratique du point de
vue de Contrôleur d'oiseaux car il n'a pas besoin d'écrire du code spécifique pour déterminer le
type exact d'Oiseau avec lequel il travaille, ou le comportement de cet Oiseau. Comment se
fait-il alors que, lorsque bouger() est appelé tout en ignorant le type spécifique de l'Oiseau, on
obtienne le bon comportement (une Oie court, vole ou nage, et un Pingouin court ou nage) ?
13
M. Lahdir (Dépt. ELN de UMMTO)