Vous êtes sur la page 1sur 13

Master 1 Prof.

Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020

Chapitre 1 : Introduction au langage Java

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.

Le langage Java possède de nombreuses caractéristiques :

- C’est un langage orienté objet


- C’est un langage compilé : avant d’être exécuté, il doit être traduit dans le langage de la
machine sur laquelle il doit fonctionner
- Il emprunte sa syntaxe en grande partie du langage C
- Les programmes Java peuvent être exécutés sous forme d’applications indépendantes ou
distribuées à travers le réseau et exécutées par un navigateur Internet sous forme d’applets.

Java a rapidement intéressé les développeurs pour quatre raisons principales :

- 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.

2 Pourquoi utiliser Java ?

2.1 Le monde sans Java

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.

2.2 Le monde avec Java

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

- Il est possible de développer des applications isolées (standalone applications), fonctionnant


avec l'interpréteur comme un programme habituel dans un langage classique mais aussi des
"applets". Les applets sont des programmes qui peuvent être téléchargés sur l’Internet puis
exécutés automatiquement quand ils sont intégrés à dans des pages HTML. Dans ce dernier
cas, l'ensemble des fichiers .class est utilisé avec un fichier HTML qui fait appel à une des
classes. Bien que les principes de programmation soient très proches, ce document traite
uniquement des applications car la philosophie est plus proche des langages classiques
(C/C++, Pascal, ADA …).

- 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

3 Utilisation du JDK (Kit de développement Java)

Permet le développement de programmes en Java. Il est constitué des outils suivants :


- javac.exe : compilateur
- java.exe : interpréteur
- jdb.exe : debugger…
-
et d’une importante librairies de classe (API).

Téléchargement : http://www.sun.com/products/index.html

Configuration :

Chemin d’accès aux exécutables


En supposant que vous avez choisi la version Windows 98. Vous devez modifier la variable
PATH du fichier autoexec.bat :
- Ouvrez à l’aide d’un éditeur de texte, le fichier autoexec.bat se trouvant dans la racine du
disque dur
- Localisez la ligne commençant par set path et ajoutez à la fin de celle-ci : set path =
c:\jdk1.2\bin

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 ».

Chemin d’accès aux classes Java


Le chemin d’accès aux classes Java peut être configuré exactement de la même façon à l’aide
de la variable classpath.

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

- Exécution : java [<options>] <fichiers-class sans extension> . Exemple : java Test

4- Principe de la programmation en Java : l’Orienté Objet

Un programme structuré (Pascal, C…) est composé de fonctions indépendantes constituées


d’instructions simples et structurés. Ainsi, les données et les fonctions qui opèrent sur elles
sont séparées. Les données apparaissent généralement en tête du programme et sont donc
visibles de toutes les fonctions qui suivent. Cette organisation pose le grave problème des effets
de bord. En entrant dans une fonction, on est jamais assuré de trouver les données dans l’état
attendu, car n’importe quelle autre fonction, même si ce n’est pas son rôle, peut les modifier.
De plus, à cause de cette séparation entre données et fonctions, de profonds bouleversements
du programme sont nécessaires quand les structures de données sont modifiées. La solution à
ces problèmes est la programmation objet. Elle est basée sur trois principes fondamentaux :
l’encapsulation, l’héritage, et le polymorphisme.

4.1 L’encapsulation

L’encapsulation des données est le premier et le plus important des concepts de la


programmation objet. Il stipule que les données et les fonctions qui opèrent sur elles sont
encapsulées dans des objets. Les seules fonctions à être autorisées à modifier les données d’un
objet sont les fonctions appartenant à cet objet. Depuis l’extérieur d’un objet, on ne peut le
modifier que par des fonctions faisant office d’interface. Ainsi, il n’est plus à craindre que des
fonctions modifient indûment des données.

6
M. Lahdir (Dépt. ELN de UMMTO)
Master 1 Prof. Semestre 2 UEM2 : Programmation Orienté Objet 2019-2020

Notion d’objet :

La programmation orientée objet consiste à modéliser informatiquement un ensemble


d'éléments d'une partie du monde réel (que l'on appelle domaine) en un ensemble d'entités
informatiques. Ces entités informatiques sont appelées objets. Il s'agit de données informatiques
regroupant les principales caractéristiques des éléments du monde réel (taille, couleur, ...).

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, ...).

Un objet est caractérisé par plusieurs notions :

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).

Une classe est composée de deux parties :

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.

Comment utiliser un 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.

Prenons l'exemple d'une ampoule électrique :

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.

Du point de vue de la programmation, une classe dispose de fonctions associées à chaque


requête possible (appelée méthodes), et lorsqu’on effectue une requête particulière sur un objet,
ces fonctions sont appelées. Dans l’exemple ci-dessus, le nom de la classe est Ampoule, le nom
de l'objet Ampoule créé est
amp. D’après l’interface, on peut demander à un objet Ampoule de s'allumer et de s'éteindre.

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.

Masquage des informations :

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é

Réutilisation d’une implémentation :

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 troisième principe de base de la programmation objet est le polymorphisme. Il passe plus


inaperçu que les précédents. Des fonctions différentes dans les classes différentes peuvent
prendre le même nom. Ainsi, dans une hiérarchie de classes d’éléments graphiques la fonction
dessiner( ) aura le même nom pour un polygone ou un cercle, cependant les techniques utilisées
pour dessiner ces éléments sont différentes. Le polymorphisme est beaucoup plus puissant qu’il
n’y paraît à première vue. Il fait économiser des identificateurs de fonctions et rend les notations
plus lisibles.

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.

On distingue généralement trois types de polymorphisme :

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 :

Le polymorphisme paramétrique, appelé généricité, représente la possibilité de définir plusieurs


fonctions de même nom mais possédant des paramètres différents (en nombre et/ou en type).
Le polymorphisme paramétrique rend ainsi possible le choix automatique de la bonne méthode
à adopter en fonction du type de donnée passée en paramètre.

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

- La méthode int addition(int, int) pourra retourner la somme de deux entiers


- La méthode float addition(float, float) pourra retourner la somme de deux flottants
- La méthode char addition(char, char) pourra définir au gré de l'auteur la somme de deux
caractères
etc.
On appelle signature le nombre et le type (statique) des arguments d'une fonction. C'est donc la
signature d'une méthode qui détermine laquelle sera appelée.

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)

Vous aimerez peut-être aussi