Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
El Mostafa DAOUDI
m.daoudi@fso.ump.ma
Septembre 2011
El Mostafa DAOUDI- p. 1
Quelques Références:
- Cours JAVA, Daoudi 2007
- Cours JAVA, Arrassen 2011
Livre:
- Titre: Programmer en JAVA ,
AuteurClaude Delnoy,
Editeur: Eyrolles
- Thinking in Java, Bruce Eckel
Ressources Internet:
- http ://www.java.sun.com
- Richard Grin: http://deptinfo.unice.fr/~grin
- Cours Mickaël BARON - 2007
- Cours Interface graphique en Java API swing, Juliette Dibie-Barthélemy mai
2005
- …..
El Mostafa DAOUDI- p. 2
Ch I. Introduction à la programmation Orientée
Objet
I. Généralité sur la Programmation Orientée Objet
• La Programmation Orientée Objet (POO) propose une
méthodologie de programmation centrée sur les objets. Où un
objet peut être vu comme une entité regroupant un ensemble de
données et de méthodes de traitement.
• Le programmeur
- Doit d’abord identifier les objets qui doivent être utilisé (ou
manipulé) par le programme: on commence par décider quels objets
doivent être inclus dans le programme.
- Va ensuite, écrire les traitements, en associant chaque traitement à
un objet donné.
El Mostafa DAOUDI- p. 3
Il s'agit donc :
- de déterminer les objets présents dans le programme.
- d'identifier leurs données .
- De définir les traitements à faire sur ses objets .
El Mostafa DAOUDI- p. 4
Intérêts de la Programmation Orientée Objet (POO)
• Programmation modulaire: Faciliter de la réutilisation de code.
• Encapsulation (Principe de la POO) et abstraction (proche du monde
réel):
– Regrouper les caractéristique dans une classe
– Cacher les membre d’une classe: choix dans les niveaux de
confidentialité
• Programmation par « composants » (chaque portion de code est isolée) :
Faciliter de l’évolution du code.
El Mostafa DAOUDI- p. 5
II. Généralités sur les objets
• L’objet est l’unité logique de la programmation orientée objet.
• Objet est une entité logiciel rassemblant des données et du code travaillant sur
ses données. Il est définie par:
– un état
– un comportement
– une identité
État : il est défini à l’aide d’attributs (Fields, appelés aussi données membres).
Ce sont des variables associées à l’objet et qui stockent des valeurs (des
informations sur d'état de l'objet).
Exemple: L’état d’un objet de type Voiture est caractérisé par les attribut :
couleur et vitesse
L’état de l’objet maVoiture est caractérisé par les données
couleur = rouge
vitesse = 240
maVoiture Nom de l’objet (identifiant)
- couleur = rouge
- vitesse = 240 Description des attributs
El Mostafa DAOUDI- p. 6
Comportement : il est caractérisée par des méthodes (appelées parfois
fonctions membres) qui permettent de modifient l’état de l’objet.
Une méthode rattachée à l’objet permet de déclencher un des
comportements associés à l’objet.
Il n’est pas possible d’agir directement sur les données d’un objet
pour modifier son état; il est nécessaire de passer par ses méthodes. On
dit qu'on « envoie un message » (fait une requête) à un objet.
Un objet peut recevoir un message qui déclenche
– une méthode qui modifie son état
et / ou
– une méthode qui envoie un message à un autre objet
Exemple:
demarrer
maVoiture moteur
El Mostafa DAOUDI- p. 7
Identité: L'objet possède une identité, qui permet de le distinguer des
autres objets, indépendamment de son état.
Résumé:
• Un objet est une variable améliorée: il stocke les données, mais on peut
effectuer des requêtes sur cet objet (on demande à l’objet de faire des
opérations sur lui-même), en envoyant un message à cet objet. Ceci est
équivalent à un appel de fonction.
• Il possède une structure interne et un comportement
• Chaque objet à son espace mémoire: la simplicité des objet mis en
œuvre, cache la complexité des programme.
• Chaque objet a un type précis: c’est-à-dire chaque objet est une instance
(variable) d’une class (type)
• Un programme est ensemble d’objets qui s’envoient des
El Mostafa DAOUDI- p. 8
Exemple: un livre à la bibliothèque est caractérisé par:
- Un titre
- Un auteur
- Un numéro d’inventaire
- Une quantité (le nombre de livres disponibles à laa biblihothèque).
Un objet de type Livre est constitué d’attributs qui caractérisent la structure de cet
objet:
Exemple d’attrinuts:
private String titre;
private String auteur
private long int numInv;
private String numClas;
Static int Qte;
El Mostafa DAOUDI- p. 9
III. Notions de classes
Une classe (ou type d’objets) représente une famille d’objets qui
partagent des propriétés communes: Les objets qui ont les mêmes
états et les mêmes comportements.
Une classe regroupe les objets qui ont :
- La même structure (même ensemble d’attributs)
- Le même comportement (même méthodes)
El Mostafa DAOUDI- p. 12
Ch II. Introduction au langage Java
I. Introduction
• Java est un langage orienté objet: l'entité de base de tout
code Java est la classe
• Créé en 1995 par Sun Microsystems
• Sa syntaxe est proche du langage C
• Il est fourni avec le JDK (Java Developpment Kit)
– Outils de développement
– Ensemble de paquetages très riches et très variés
• Multi-tâches (threads)
• Portable grâce à l’exécution par une machine virtuelle
El Mostafa DAOUDI- p. 13
• En Java, tout se trouve dans une classe. Il ne peut y
avoir de déclarations ou de code en dehors du corps
d'une classe.
• La classe elle même ne contient pas directement du
code.
– Elle contient des attributs.
– et des méthodes (équivalents à des fonctions).
• Le code se trouve exclusivement dans le corps des
méthodes, mais ces dernières peuvent aussi contenir
des déclarations de variables locales (visibles
uniquement dans le corps de la méthode).
El Mostafa DAOUDI- p. 14
II. Environnement de Programmation
1. Compilation
• La compilation d’un programme Java ne traduit pas
directement le code source en fichier exécutable. Elle traduit
d’abord le code source en un code intermédiaire appelé
«bytecode». C’est le bytecode qui sera ensuite exécuté par une
machine virtuelle (JVM ; Java Virtual Machine). Ceci permet
de rendre le code indépendant de la machine qui va exécuter le
programme.
El Mostafa DAOUDI- p. 16
2. Exécution du bytecode
• Le bytecode doit être exécuté par une JVM. Cette JVM n'existe pas;
elle est simulée par un programme qui
– lit les instructions (en bytecode) du programme .class,
– les traduit dans le langage machine relatif à la machine sur laquelle
il sera exécuté.
– Lance leur exécution
• Pour exécuter, Sun fournit le programme java qui simule une JVM. Il
suffira d’utiliser la commande:
java MonPremProg
El Mostafa DAOUDI- p. 17
3. Mon premier programme en Java
Considérons le code source suivant:
El Mostafa DAOUDI- p. 18
Dans le cas de l’environnement JDK de SUN.
El Mostafa DAOUDI- p. 19
L’exécution du programme MonPremProg affiche à l’écran,
comme résultat, la chaîne de caractères:
Bonjour: mon premier programme Java
grâce à l’instruction:
System.out.println(" Bonjour: mon premier programme Java ");
El Mostafa DAOUDI- p. 20
• De manière générale, dans tout programme autonome destiné
à être exécuté doit contenir une méthode particulière
nommée main() définie de la manière suivante:
public static void main(String args[]) {
/* corps de la méthode */
}
• Le paramètre args de la méthode main() est un tableau
d’objets de type String. Il n’est pas utilisé mais, il est exigé
par le compilateur Java.
• La classe contenant la méthode main() doit obligatoirement
être public afin que la machine virtuelle y accès. Dans
l’exemple, le contenu de la classe MonPremProg est réduit à
la définition d’une méthode main().
El Mostafa DAOUDI- p. 21
• Un fichier source peut contenir plusieurs classes mais
une seule doit être public(ici PremProg).
El Mostafa DAOUDI- p. 22
Ch. III Les classes et les Objets
I. Création d’une classe
Pour créer une classe (un nouveau type d’objets) on utilise le mot clé class.
La syntaxe pour créer une classe de nom ClasseTest est la suivante:
class ClasseTest{ /* ClasseTest est le nom de la classe à créer */
/* Corps de la classe
- Description des attributs (données membres)
- Description des méthodes
*/
}
Pour les commentaire on utilise:
// pour un commentaire sur une seule ligne
/* pour une commentaire étalé sur
plusieurs lignes, et doit terminer avec */
El Mostafa DAOUDI- p. 23
Code java de la classe Rectangle (voir avant):
El Mostafa DAOUDI- p. 26
• Les valeurs des attributs peuvent être différents.
Chaque instance d’une classe possède ses propres valeurs pour chaque attribut
(chaque objet a son propre état).
Rectangle
« instance»
El Mostafa DAOUDI- p. 27
2. Etapes de création des Objets
Contrairement aux types primitifs, la création d’objets se passe en deux
étapes:
- Déclaration de l’objet
- Création de l’objet
Syntaxe:
NomDeClasse objetId;
NomDeClasse objetId1, objetId2,….;
-
NomDeClasse est la nom de la classe.
- Déclare objetId1, objetId2, … comme variables de type NomClasse
El Mostafa DAOUDI- p. 28
Attention:
- La déclaration d’une variable de type primitif réserve un emplacement
mémoire pour stocker la variable
- Par contre, la déclaration d’un objet, ne réserve pas une place mémoire
pour l’objet, mais seulement un emplacement pour une référence à cet
objet.
les objets sont manipulés avec des références
El Mostafa DAOUDI- p. 29
Exemple:
Considérons la classe ClasseTest
class ClasseTest {
// corps de la classe ClasseTest
}
l’instruction:
ClasseTest objA;
- Déclare objA comme objet (variable) de type ClasseTest:
- Définit le nom et le type de l’objet.
- Déclare que la variable objA est une référence à un objet de la classe
ClasseTest. Cela veut dire que on va utiliser une variable objA qui
référencera un objet de la classe ClasseTest.
- Aucun objet n’est créé: un objet seulement déclaré vaut « null ».
objA
null
El Mostafa DAOUDI- p. 30
2.2. Création d’un objet
Après la déclaration d’une variable, on doit faire la création (et
allocation) de la mémoire de l’objet qui sera référencé par cette
variable.
- La création doit être demandé explicitement dans le programme en
faisant appel à l’opérateur new.
- La création réserve de la mémoire pour stocker l’objet et initialise les
attributs.
El Mostafa DAOUDI- p. 31
Exemple
class ClasseTest {
/* Corps de la classe ClasseTest */
}
En générale:
1. Chaque objet met ses données membres dans sa propre zone mémoire.
2. Les données membres ne sont partagées entre les objets de la même
classe.
El Mostafa DAOUDI- p. 32
Exemple : Considérons la classe rectangle
public class Rectangle{
int longueur;
int largeur;
int x;
int y;
public static void main (String args[]) {
Rectangle rectangleR1; /* déclare une référence sur l’objet rectangleR1 */
rectangleR1 = new Rectangle(); /* création de l’objet rectangleR1 */
// rectangle R1 est une instance de la classe Rectangle
// Les deux expressions peuvent être remplacées par :
// Rectangle rectangleR1=new Rectangle();
}
}
El Mostafa DAOUDI- p. 33
2.3. Initialisation par défaut
La création d’un objet entraîne toujours une initialisation par
défaut de tous les attributs de l’objet même si on ne les
initialise pas:
----------------------------------------------------------------
Type | Valeur par défaut |
---------------------------- |-----------------------------------|
boolean | false |
char | ‘\u0000’ (null) |
byte | (byte) 0 |
short | (short) 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0 |
Class | null |
------------------------------------------ ----------------------|
El Mostafa DAOUDI- p. 34
Attention: Cette garanti d’initialisation par
défaut ne s’applique pas aux variables locales
(variables déclarée dans un bloc par exemple
variables locales d’une méthode) (voir plus
loin).
El Mostafa DAOUDI- p. 35
III. Définition des méthodes
En Java, chaque fonction est définie dans une classe . Elle est définie
par :
– un type de retour
– un nom
– une liste (éventuellement vide) de paramètres typés en entrée
– une suite d’instructions (un bloc d’instructions) qui constitue le corps
de la méthode
Syntaxe:
typeRetour nomMethode ( «Liste des paramètres » ) {
/*
corps de la méthode qui peut contenir l’instruction
*/
}
El Mostafa DAOUDI- p. 36
- nomMethode : c’est le nom de la méthode
- « Liste des paramètres » : liste des arguments de la méthode.
Elle définit les types et les noms des informations qu’on
souhaite passer à la méthode lors de son appel.
- typeRetour : c’est le type de la valeur qui sera retournée par
la méthode après son appel. Si la méthode ne fournit aucun
résultat, alors typeRetour est remplacé par le mot clé void.
Remarque:
La valeur retournée par la fonction est spécifiée dans le corps
de la méthode par l’instruction de retour:
return expression;
ou
return; // (possible uniquement pour une fonction de type void)
El Mostafa DAOUDI- p. 37
- La signature d’une méthode est: Le nom de la méthode et
l’ensemble des types de ses paramètres.
- En Java, le type de la valeur de retour de la méthode ne fait pas
partie de sa signature (au contraire de la définition habituelle
d'une signature)
Passage des paramètres
Le mode de passage des paramètres dans les méthodes dépend de
la nature des paramètres :
- par valeur pour les types primitifs.
- par valeur des références pour les objets: la référence est
passée par valeur (i.e. le paramètre est une copie de la
référence), mais le contenu de l’objet référencé peut être
modifié par la fonction (car la copie de référence pointe vers
le même objet…) :
El Mostafa DAOUDI- p. 38
Exemple:
class ClasseTest {
void methode1(int j){
j+=12;
}
void methode2() {
int j = 3;
methode1(j);
System.out.println(j=" + j); // j=3
}
}
El Mostafa DAOUDI- p. 39
IV. Accès aux membres d’un objet
El Mostafa DAOUDI- p. 41
2. Accès aux méthodes: appels des méthodes
• Les méthodes ne peuvent être définie que comme des
composante d’une classe.
• Une méthode ne peut être appelée que pour un objet.
• L’appel d’une méthode pour un objet se réalise en
nommant l’objet suivi d’un point suivi du nom de la
méthode et de sa liste d’arguments:
nomObjet.nomMethode(arg1, ….).
où
nomObjet: nom de la référence à l’objet
nomMethode: nom de la méthode.
El Mostafa DAOUDI- p. 42
Exemple 1: soit f () une méthode qui prend un paramètre de
type double et qui retourne une valeur de type int.
class ClasseTest {
float x;
int i;
boolean b;
int f(double x) {
int n;
// corps de la fonction f()
return n;
}
}
ClasseTest objA = new ClasseTest(); // créer un objet objA;
int j = objA.f(5.3); // affecte à j la valeur retournée par f()
El Mostafa DAOUDI- p. 43
Exemple 2: Considérons la classe Rectangle dotée en plus de la méthode
initialise qui permet d’affecter des valeurs à l’origine (aux attributs x et y).
public class Rectangle{
int longueur, largeur;
int x,y;
void initialise_origine(int x0,int y0) {
x=x0; y=y0;
}
public static void main (String args[]) {
Rectangle r1;
r1.longueur=4; r1.largeur=2;
r1. initialise_origine(0,0); // affecte 0 aux attribut x et y
// Erreur car l’objet n’est pas encore créé. Il faut tout d’abord le créer
}
}
El Mostafa DAOUDI- p. 44
Exemple : crée à l’origine un rectangle r1 de longueur 4 et de largeur 2
public class Rectangle{
int longueur, largeur;
int x,y;
void initialise_origine(int x0, int y0) {
x=x0; y=y0;
}
public static void main (String args[]) {
Rectangle r1=new Rectangle ();
r1.longueur=4; r1.largeur=2;
r1. initialise_origine(0,0);
}
}
El Mostafa DAOUDI- p. 45
V. Encapsulation
• Une classe permet d’envelopper les objets : Un objet est vu par le
reste du programme comme une entité opaque.
• L'enveloppement [wrapping] des attributs et méthodes à l'intérieur
des classes plus (+) le contrôle d'accès aux membre de l’objet est
appelé encapsulation.
• Le contrôle d'accès aux membre de l’objet est appelé cacher
l'implémentation: Les membres publiques sont vus de l'extérieur
mais les membres privés sont cachés.
• L'encapsulation est 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.
El Mostafa DAOUDI- p. 46
• Possibilité d’accéder aux attributs d’une classe Java mais
ceci n’est pas recommandé car contraire au principe
d’encapsulation: Les données (attributs) doivent être
protégés.
• Accessibles pour l’extérieur par des méthodes particulières
(sélecteurs
• Plusieurs niveaux de visibilité peuvent être définis en
précédant, la déclaration d’un attribut, d’une méthode ou
d’un constructeur, par un modificateur : private, public ou
protected.
El Mostafa DAOUDI- p. 47
Spécificateurs d’accès:
L'encapsulation permet de définir 3 niveaux de visibilité des éléments de
la classe.
Ces 3 niveaux de visibilité (public, private et protected) définissent les
droits d'accès aux données suivant le type d’accès:
• public: accès depuis l’extérieure (par une classe quelconque)
• private : accès depuis l’intérieure (accès par une méthode de la classe
elle-même): sauf les méthodes internes de ce type qui ont droit à
accéder à ces définitions.
• protected: se comporte comme private avec moins de restriction. Une
classe dérivée à un accès aux membres protected mais pas aux
membres private.
• Accès par défaut: lorsqu’aucun de ces spécificateurs n’est mentionné.
Encapsulation "usuelle": les attributs sont privés, et les méthodes sont
publiques (sauf celles à usage interne).
El Mostafa DAOUDI- p. 48
Exemple 1: modification depuis l’extérieur d’un champs private
class ClasseTest {
public int x;
private int y;
public void initialise (int i, int j){
x=i;
y=j; // accès à l’attribut private y depuis l’intérieure
}
}
public class TestA{ // fichier source de nom TestA.java
public static void main (String args[]) {
ClasseTest objA;
objA=new ClasseTest(); // On peut aussi déclarer ClasseTest objA=new ClasseTest();
objA.initialise(1,3); // x vaut 1 et y vaut 3
objA.x=2; // x vaut maintenant 2. On peut accéder à x car il est public
objA.y=3;
// ne compile pas car accès à un attribut privé: y attribut private
}
}
El Mostafa DAOUDI- p. 49
Exemple 2: affichage depuis l’extérieur d’un champs private.
class ClasseTest {
public int x;
private int y;
public void initialise (int i, int j){
x=i;
y=j; // accès à l’attribut private y depuis l’intérieure
}
}
public class TestA{ // fichier source de nom TestA.java
public static void main (String args[]) {
ClasseTest objA;
objA=new ClasseTest(); // On peut aussi déclarer ClasseTest objA=new ClasseTest();
objA.initialise(1,3); // x vaut 1 et y vaut 3
System.out.println(" x= "+objA.x); // affiche x = 1. x public, on peut y accéder
System.out.println(" y= "+objA.y);
// ne compile pas car : accès à y qui est un attribut y privé
}
}
El Mostafa DAOUDI- p. 50
IV. Méthodes d’accès aux valeurs des variables depuis l’extérieur (voir
TD)
Comment peut on accéder à la valeur d’une variable protégée ??
Considérons la classe etudiant qui a les champs nom et prenom private.
Exemple:
class Etudiant {
private String nom, prenom;
public initialise(String st1, String st2){
nom=st1; prenom=st2;
}
}
public class MethodeStatic{
public static void main(String[] argv) {
Etudiant e= new Etudiant("Mohammed","Ali");
System.out.println("Nom = "+e.nom);
// ne compile pas car le champs nom est privé
/* comment faire pour afficher le nom de l’étudiant e; ??
}
}
El Mostafa DAOUDI- p. 51
Pour afficher la valeur de l’attribut nom (champs private), on définie
Un accesseur (méthode getNom) qui est une méthode permettant de
lire, depuis l’extérieur, le contenu d'une donnée membre protégée.
Exemple:
class Etudiant {
private String nom, prenom;
public initialise(String nom, String Prenom){
this.nom=nom; this.prenom=prenom;
}
public String getNom (){
return nom;
}
public String getPrenom (){
return prenom
}
}
El Mostafa DAOUDI- p. 52
public class MethodeStatic{
public static void main(String[] argv) {
Etudiant e= new Etudiant("Mohammed","Ali");
e.initialise("Mohammed","Ali");
System.out.println("Nom = "+e.getNom());
System.out.println("Prenom = "+e.getPrenom());
}
}
El Mostafa DAOUDI- p. 53
Comment peut-on modifier (depuis l’extérieur) le contenu d'un attribut
privé ?.
Exemple:
class Etudiant {
private int cne;
}
El Mostafa DAOUDI- p. 54
Pour modifier la valeur de l’attribut nom (champs private), on défine
Un modificateur (mutateur) qui est une méthode permettant de
modifier le contenu d'une donnée membre protégée.
Exemple:
class Etudiant {
private int cne;
public void setCNE (int cne){
this.cne=cne;
}
}
public class MethodeStatic{
public static void main(String[] argv) {
Etudiant e= new Etudiant();
e.setCNT(23541654);
}
}
El Mostafa DAOUDI- p. 55
V. Autoréférences: emploi de this
- Possibilité au sein d’une méthode de désigner explicitement
l'instance courante : faire référence à l’objet qui a appelé cette
méthode.
- Par exemple pour accéder aux attributs "masqués" les par
paramètres de la méthode.
class ClasseA {
….
public void f(….) {
…… // ici l’emploi de this désigne la référence à l’objet
// ayant appelé la méthode f
}
}
El Mostafa DAOUDI- p. 56
Exemple:
class Etudiant {
private String nom, prenom;
public initialise(String st1, String st2) {
nom = st1;
prenom = st2;
}
}
Comme les identificateurs st1 et st2 sont des arguments muets pour
la méthode initialise(), alors on peut les noter nom et prenom qui
n’ont aucune relation avec les champs private nom et prenom.
Dans ce cas la classe Etudiant peut s’écrire comme suit:
El Mostafa DAOUDI- p. 57
class Etudiant {
private String nom, prenom;
public initialise(String nom, String prenom){
this.nom=nom;
this.prenom=prenom;
}
}
El Mostafa DAOUDI- p. 58
VI. Champs et méthodes de classe
1. Champs de classe ((variable de classe)
Considérons la définition simpliste suivante:
class ClasseTest {
int n;
double y;
}
El Mostafa DAOUDI- p. 59
Certaines attributs peuvent être partagées par toutes les
instances d’une classe. C’est-à-dire ils peuvent être définis
indépendamment des instances (objets):
Par exemple le nombre d’étudiants = le nombre d’objets
étudiant créés.
El Mostafa DAOUDI- p. 60
Considérons la classe:
class ClasseTest {
static int n; // la valeur de n est partagée par toutes les instances
double y;
}
Soient objA1 et objA2 deux instances différentes.
ClasseTest objA1=new ClasseTest(), objA2=new ClasseTest();
objA1 et objA2 partagent la même variable n:
objA1.n et objA2.n désignent la même donnée. La valeur de
l’attribut n est indépendant de l’instance (objet).
- Pour y accéder, on utilise le nom de la classe
ClasseTest.n // champs (statique) de la classe ClasseTest
El Mostafa DAOUDI- p. 61
Exemple1:
class ClasseTest {
int n;
double y;
}
public class MethodeStatic{
public static void main(String[] argv) {
ClasseTest objA1=new ClasseTest();
objA1.n+=4; // objA1.n vaut 4;
El Mostafa DAOUDI- p. 62
Exemple2:
class ClasseTest {
static int n; // la valeur de n est partagée par toutes les instances
float y;
}
public class MethodeStatic{
public static void main(String[] argv) {
ClasseTest objA1=new ClasseTest();
objA1.n+=4; // objA1.n vaut 4;
// équivalent à ClasseTest.n=4;
ClasseTest objA2=new ClasseTest();
// objA2.n = ?
// objA2 vaut 4 car champs statique .
}
}
El Mostafa DAOUDI- p. 63
2. Méthodes de classe
Ce sont des méthodes qui ont un rôle indépendant d’un objet
spécifique. Elles exécutent une action indépendante d’une
instance particulière de la classe
El Mostafa DAOUDI- p. 64
Exemple
class ClasseTest{
…
private static int n; // champs de classe
private float x; // champs usuel
public static void f() { // méthode de clase
… //ici, on ne pas accéder au champs x, champs usuel
… // ici on peut accéder au champs statique n.
}
}
El Mostafa DAOUDI- p. 65
VII. Le mot clé final
L’attribut final indique que la valeur de la variable ne peut être
modifiée : on pourra lui donner une valeur une seule fois dans
le programme.
El Mostafa DAOUDI- p. 67
Constantes de classe
• Usage
– Ce sont des variables de classes déclarées avec le mot-clé final
– Ce sont des constantes liées à une classe
– Elles sont écrites en MAJUSCULES
– Pour y accéder, il faut utiliser non pas un identificateur d’objet
mais le nom de la classe
Exemple:
public class Galerie {
public static final int MASSE_MAX = 150;
}
if (maVoiture.getWeightLimite() <= Galerie.MASSE_MAX)
{...}
El Mostafa DAOUDI- p. 68
Exemple (voir TD):
El Mostafa DAOUDI- p. 69
Ch. IV. Généralités sur la structure lexicale de Java
I. Variables
• Les variables d’instances:
– sont déclarées en dehors de toute méthode.
– conservent l’état d’un objet, instance de la classe
– sont accessibles et partagées par toutes les méthodes de la classe
• Les variables locales:
– sont déclarées à l’intérieur d’une méthode
– conservent une valeur utilisée pendant l’exécution du bloc dans
lequel elles sont définies.
– ne sont accessibles que dans le bloc dans lequel elles ont été
déclarées.
• Déclaration des variables: En Java, toute variable utilisée doit être
déclarée avant son utilisation. La syntaxe de la déclaration :
type identificateur;
El Mostafa DAOUDI- p. 70
Où
- type désigne le type de la variable déclarée
- identificateur est une suite de caractères pour désigner les
différentes entités manipulés par un programme: variables,
méthode, classe, objet, …
El Mostafa DAOUDI- p. 71
Mots réservé du langage Java
El Mostafa DAOUDI- p. 72
II. Style de programmation non standard
Conventions de nommage en Java: pas obligatoires, mais très
fortement recommandées (essentiel pour la lisibilité du code et
sa maintenance).
• Identificateur: pas d'emploi de $ (et de caractères non ASCII)
• Nom de classe :
– Si le nom de la classe est composé de plusieurs mots, ils
sont accolés (on ne les sépare la trait _ souligné).
– Commencez chaque mot par une majuscule: exemple:
HelloWorld, ClasseTest, MonPremierProgramme.
El Mostafa DAOUDI- p. 73
• Nom de variable ou méthode :
– Si le nom est composé d’un seul mot: la première lettre est
miniscule.
– Si le nom est composé par plusieurs mots, ils sont accolés et
respecte la règle suivante:
• La première lettre du premier mot est miniscule.
• La première lettre des autres mots est majuscule, exemple:
maPremiereNote, initialiseAttribut(), calculTaux(), main(),
objEtudiant, …
• Les constantes: majuscules et séparation des mots par _ :
VALEUR_MAX;
• Usage non recommandé :
– mapremierevariable
– ma_premiere_variable
El Mostafa DAOUDI- p. 74
Les commentaires
• Sur une seule ligne : style C++
// Ceci un commentaire
int taux = 75; // taux de réussite
• Sur plusieurs lignes : style C
/* Première ligne du commentaire
suite du commentaire */
El Mostafa DAOUDI- p. 75
Mise en page des programmes
La mise en page d’un programme Java est libre.
- Une instruction peut être étendue sur plusieurs lignes.
- Une ligne peut comporter plusieurs instructions
El Mostafa DAOUDI- p. 76
III. L’affectation
• L’opération d’affectation affecte ( assigne) une valeur à une
variable. Elle est réalisée au moyen de l’opérateur « = ».
la syntaxe : identificateur = valeur ;
Signifie prendre la valeur du coté droit et la copier du coté
gauche.
• identificateur : désigne une variable.
• valeur : est une constante, une variable ou une expression qui
retourne une valeur du même type que la variable référencée
par identificateur .
El Mostafa DAOUDI- p. 77
Cas des types primitifs
• Soient a et b de type primitif. L’affectation a=b; signifie que le
contenu de b est copié dans a.
Exemple:
a=2;
b=15;
a=b; // La nouvelle valeur de a est 15
après affectation a et b existent et ont tous la même valeur 15.
El Mostafa DAOUDI- p. 78
Cas des Objets
Soient objA est objB deux objets,
L’affectation objA=objB; signifie qu’on copie la référence de
objB dans objA.
1. Les références objA et objB pointeront vers le même objet
référencé par objB.
2. L’objet qui a été initialement référencé par objA existe
toujours, mais on n’a aucun contrôle sur lui (il reste
inaccessible).
El Mostafa DAOUDI- p. 79
Exemple:
class A {
public int i;
}
public class TestAffectation {
public static void main(String[] args) {
A a=new A(); A b=new A();
a.i=6; b.i=11;
a=b; // a et b contiennent la même référence, on a: a.i=11
a.i=20; // b.i = 20
b.i=13; // a.i = 13
}
a= new A() Instance Instance
a a
a a
a= b
Instance b Instance
b b b
b= new B()
El Mostafa DAOUDI- p. 80
IV. Types de données en Java
2 grands groupes de types de données sont manipulés par Java:
– types primitifs
– objets (instances de classe)
El Mostafa DAOUDI- p. 81
1. Types primitifs
• Booléen:
Boolean : prend deux valeurs true ou false
• Caractère (un seul caractère) :
char : codé sur 2 octet par le codage Unicode
• Nombres entiers :
byte: représenté sur 1 octet (8 bits),
short: représenté sur 2 octets (16 bits),
int : représenté sur 4 octets (32 bits),
long : représenté sur 8 octets (64 bits).
• Nombres à virgule flottante :
float : flottant (IEEE 754) 32-bit
double : flottant (IEEE 754) 64-bit
El Mostafa DAOUDI- p. 82
1.1. Type booléen
• Sert à représenter une valeur logique du type vrai/faux:
– Une variable de type booléen est déclaré par:
boolean b;
b prend une des deux valeurs true ou false
• C’est un véritable type:
– Il est retourné par les opérateurs de comparaison
– Il est attendu dans tous les tests
• ne peut pas être converti en entier
El Mostafa DAOUDI- p. 83
1.2. Type caractère
• Permet de manipuler des caractères: Java représente un caractère sur 2 octets (16 bits)
16-bit => 65536 valeurs : presque tous les caractères de toutes les écritures.
Ne sont affichables que si le système possède les polices de caractères adéquates.
• Une variable de type caractère est déclaré par: char c1,c2;
• Constantes de type caractère doivent être écrites entre simples quottes .
Exemple : 'a‘ , 'Z' , ‘E’
Les caractères disposant d’une notation spéciale.
El Mostafa DAOUDI- p. 84
1.3. Nombres entiers
- Les valeurs min/max
– byte : codé sur sur 1 octet = 8 bits
– short : compris entre –32 768 et 32 767
– int : compris entre –2.147 483 648 et 2 147 483 647
– long : compris entre -923 372 036 854 775 808
et 923 372 036 854 775 807
El Mostafa DAOUDI- p. 85
• Constantes nombres: Une constante « entière » est de type int. Si elle est
suffixée par « L » ou « l » alors elle est de type long.
Exemple:
108 // 108 constante de type int, représenté sur 32 bits
108L // 108 constante de type long, représenté sur 64 bits
• Représentation en octal (8bits) et hexadécimale (16 bits).
Exemple 1:
014 // 14 en octal (base 8) = 12 en décimal
0xA7 // A7 en hexadécimal (base 16) = 167 en décimal
El Mostafa DAOUDI- p. 86
Types des résultats des calculs
Avec des nombres entiers
• Tout calcul entre entiers donne un résultat de type int
• si au moins un des opérandes est de type long, alors le résultat est
de type long
Exemple:
byte b1 = (byte)20;
byte b2 = (byte)15;
byte b3 = b1 + b2;
Provoquera une erreur à la compilation car :
(b1 + b2) est de type int (codé sur 32 bits) alors que b3 est de type
byte (codé sur 8 bits seulement).
El Mostafa DAOUDI- p. 87
1.4. Les nombres flottants
• float : environ 7 chiffres significatifs ;
– Valeur absolue (arrondie) maximal 3,4 x 1038 ( constante prédéfinie
Float.MAX_VALUE)
– Valeur absolue (arrondie) minimal 1,4 x 10-45 (constante prédéfinie
Float.MIN_VALUE)
El Mostafa DAOUDI- p. 88
Constantes nombres
• Une constante réelle est par défaut elle est de type double.
• Pour spécifier un float, il faut la suffixée par « F » ou « f ».
• Conversion automatique (implicite) : seulement float double
Exemple:
.567e2 // 56,7 de type double
5.123E-2F // 0,05123 de type float
float x=2.5f //ok
double y = 2.5; //ok
El Mostafa DAOUDI- p. 89
2. Type objet: Constante null
• null : valeur d'une "référence vers rien" (pour tous
types de références)
• Elle indique qu’une variable de type non primitif ne
référence rien) ; convient pour tous les types non
primitifs
El Mostafa DAOUDI- p. 90
3. Transtypage
• Java est un langage fortement typé
• Dans certains cas, il est nécessaire de forcer le programme à
changer le type d’une expression. On utilise pour cela le cast
(transtypage) :
(type-forcé) expression
Exemple:
int i=13; // i codé sur 32 bit; 13 constante int codée sur 32 bits
byte b=i; // Erreur: pas de conversion implicite int byte
El Mostafa DAOUDI- p. 91
Casts autorisés
• En Java, 2 seuls cas sont autorisés pour les casts :
– entre types primitifs,
– entre classes mère/ancêtre et classes filles.
El Mostafa DAOUDI- p. 92
3.1. Casts entre types primitifs
Un cast entre types primitifs peut occasionner une perte de données sans
aucun avertissement ni message d'erreur.
// b vaut 13 car conversion de 32 bits vers 8 bit (On considère les 8 bits
de poids le plus faible). i est un entier « petit »
int i = 130;
b = (byte)i; // b = -126 ! Pourqoui ???
El Mostafa DAOUDI- p. 93
• Une affectation entre types primitifs peut utiliser un cast implicite si elle ne
provoque aucune perte
Exemple:
byte =120;
Ne provoque pas d’erreur (caste implicite) car 120 est dans max/min pour les
byte.
byte b=130;
Provoque une erreur "cannot convert from int to byte " car 130 hors max/min.
Dans ce cas le cast explicite est obligatoire. Mais attention au perte
d’information:
byte b=(byte)130; // renvoie -126.
El Mostafa DAOUDI- p. 94
• Les casts de types « flottants » vers les types entiers tronquent les
nombres :
float x=1.99;
int i = (int)x; // i = 1, et pas 2. On fait une troncature et non un
arrondie.
int x = 10, y = 3;
double z;
z=x/y; // donne z=3.0; car x/y donne 3
si on veut que z=3.3333.. et pas 3.0
z = (double)x / y; // cast de x suffit
El Mostafa DAOUDI- p. 95
• De même, on peut affecter un entier à une variable de type nombre à
virgule flottante
float x; int i;
x=i;
• Un cast peut provoquer une simple perte de précision : la conversion
d'un long vers un float peut faire perdre des chiffres significatifs mais
pas l'ordre de grandeur.
El Mostafa DAOUDI- p. 96
3.2. Casts entre entiers et caractères
• Ils font correspondre un entier à un caractère qui a
comme code Unicode la valeur de l’entier
• La correspondance char → int, long s’obtient par
cast implicite
• Le code d’un char peut aller de 0 à 65.535 donc
char → short, byte nécessite un cast explicite (short
ne va que jusqu’à 32.767)
• Les entiers sont signés et pas les char donc long, int,
short ou byte → char nécessite un cast explicite
El Mostafa DAOUDI- p. 97
Tableau récapitulatif de conversion de types
El Mostafa DAOUDI- p. 98
V. Principaux opérateurs
• affectation : =
• arithmétiques : + - * / %
• comparaisons : < <= > >= == !=
• booléens : && || ! ^
• opérations bit-à-bit (sur les entiers) :
& | ^ ~ << >> >>>
• opération et affectation simultanées :
+= -= *= /= %= &= |=
^= <<= >>= >>>=
• pré/post-incrémentation : ++
pré/post-décrémentation : --
• opérateur ternaire : ?:
• création tableau ou objet (allocation mémoire) :
new
• test de type des références : instanceof
El Mostafa DAOUDI- p. 99
VI. Notion de portée et de durée de vie des objets
• Un bloc est un ensemble d’instructions délimité par les accolades { et }
• Les blocs peuvent être emboîtés les uns dans les autres
• On peut grouper plusieurs instructions en un bloc délimité par des accolades { et }.
Le concept de portée fixe simultanément la visibilité et la durée de vie des noms
définis dans cette portée.
Exemple 1:
int a=1, b=2;
{ //début de bloc
int x=a;
x = 2*a+b;
} //fin de bloc
x = 3; //ERREUR: x n’est pas connu ici
• Remarque : La portée ( zone de validité de la déclaration) d'une variable va de sa
déclaration jusqu'à la fin du bloc où elle est déclarée. Elle est fixée par les accolades
{ }.
Remarque:
- La référence ObjA disparaît à la fin de la portée,
- par contre l’objet qui a été référencé par objA existe toujours, mais on
n’a aucun contrôle sur lui (il reste inaccessible).
Les objets n’ont pas la même durée de vie que les types primitifs.
• Il intervient
– quand le système a besoin de mémoire
– ou, de temps en temps, avec une priorité faible
if (exprBool) {
instructions; // exécutées si exprBool retourne true
}
if (exprBool) {
instructions1 ; // exécutées si exprBool retourne true
}
else {
instructions2; // exécutées si exprBool retourne false
}
Est équivalente à:
if (expressionBooléenne) {
expression1;
}
else {
expression2;
}
El Mostafa DAOUDI- p. 108
Exemple:
int x, y;
if (x % 2 == 0)
y = x + 1;
else
y = x;
Est équivalent à
int x;
int y = (x % 2 == 0) ? x + 1 : x;
while (expressionBooléenne) {
instructions; // corps de de la boucle
}
- Répétition « faire tant que »: le cors de la boucle est exécuté au moins une fois.
do {
instructions; // corps de de la boucle
} while (expressionBooléenne);
Remarque: Dans le cas où le corps de la boucle est formée d’une seule instruction pas
besoin de mettre les accolades { } pour marquer le début et la fin du bloc.
Attention:
En java la taille des tableaux n’est pas fixée à la déclaration. Elle est fixée
quand l’objet tableau sera effectivement créé.
- Déclaration et création.
int [] tab = new int[5];
class TestArguments {
public static void main(String[] args) {
for (int i=0; i < args.length; i++)
System.out.println(“argument “+i+ “ = “+args[i]);
}
}
$ javac TestArguments
$ java TestArguments arg1 arg2
Le programme affichera:
argument 0 = arg1
argument 1 = arg2
Copie nb éléments du tableau src (source) à partir de l’indice srcPos et les affecte
dans le tableau dest (destination) à partir de l’indice destPos.
Exemple:
import java.lang.*
System.arraycopy(tab1, 6, tab2, 2, 50);
copie de 50 éléments de tab1 à partir de l’indice 6 et les affecte
dans tab2 à partir de l’indice 2
int[] tab1,tab2;
tab1=new int[10];
tab2=new int[10];
// initialisation de tab1 et tab2
boolean b=Arrays.equals(tab1,tab2);
if (b) {
…….}
else { ………..}
// Chaque élément du tableau contient une référence vers un objet de type Etudiant
etudiantSMI[0].setCNE(11225467);
Entraîne successivement:
1. initialisation implicite (par défaut) des champs n et p de l’objet objA à 0
2. initialisation explicite: On affecte au champ n la valeur 10 (la valeur
figurant dans sa déclaration).
3. exécution des instruction du constructeur: Le corps du constructeur n’est
exécuté qu’après l’initialisation par défaut et l’initialisation explicite.
class Etudiant {
private String nom, prenom; // Variables d’instance
private int codeNatEtudiant;
public Etudiant(String n, String p) { // Constructeur
nom = n;
prenom = p;
}
public Etudiant(String n, String p, int cne) {// Constructeur
nom = n;
prenom = p;
codeNatEtudiant = cne;
}
}
class Etudiant {
private String nom, prenom; // Variables d’instance
private int codeNatEtudiant;
public Etudiant(String n, String p) { // Constructeur
nom = n;
prenom = p;
}
public Etudiant(String n, String p, int cne) {// Constructeur
this( n,p); // appel au constructeur Etudiant(String,String);
codeNatEtudiant = cne;
}
}
Remarques2:
– Java, ne permet pas l’héritage multiple. Il permet l’héritage simple
uniquement: chaque classe a une et une seule classe mère dont elle
hérite les variables et les méthodes.
– C++ permet l’héritage multiple.
Sortie:
Classe de Base : 314
Classe dérivée1: 7 , 307
Classe dérivée2: 7
Pourquoi ??
Sortie:
Classe de Base :
Classe dérivée1:
Classe dérivée2:
Règles
On peut avoir les mêmes méthodes dans des classes héritant
les unes des autres. Dans ce cas, c'est la classe la plus
dérivée de l'objet qui détermine la méthode à exécuter, sans
que le programmeur ait à faire des tests sur le type de l'objet
à traiter (voir exemple suivant).
B - La classe F hérite de C
C* *: signifie redéfinition de f().
Dans class A: la méthode f() de A
Dans classe B: la méthode f() de A
Dans classe D: la méthode f() de D
E Dans classe E: la méthode f() de A
D* F
Dans classe C: la méthode f() de C
Dans classe F: la méthode f() de C
- Soit B une classe qui hérite de la classe A, et soit f() une méthode définie dans
A et redéfinie dans B.
- Soit C une classe qui hérite de la classe B.
A a = new B();
a.f(); // La méthode f() appelée est celle définie dans B.
Maintenant si on:
A a = new C(); // ok car C hérite de B qui hérite de A
a.f();
Si la méthode f() est redéfinie dans C alors la méthode appelée est celle définie
dans C.
Si la méthode f() n’est redéfinie dans C alors c’est la méthode f() redéfinie dans B
qui est appelée.
Principe
• Principe fondamental = séparer la détection et le traitement des
anomalies :
- signaler tout problème dès sa détection.
- mais regrouper le traitement des problèmes ailleurs, en fonction de
leur type
• Plutôt que de compliquer le code du traitement normal, on traite les
conditions anormales à part
• Le traitement « normal » apparaît ainsi plus simple et plus lisible
try {
/* Code dans lequel une exception peut se produire */
}
La gestion des exceptions est obtenue par des blocs catch, où un bloc catch est associé à
une exception donnée.
Attention: Le bloc catch doit être juste après le bloc try, sinon erreur de compilation.
catch ( Type1Exception e) { // de type Type1Exception qui hérite de Exception
/* code de la gestion des exceptions */
}
catch ( Type2Exception e) { // de type Type2Exception qui hérite de Exception
/* code de la gestion des exceptions */
}
…..
L’appel de Point(-2,4); génère une exception, donc un saut est effectué vers le bloc catch().
L’exécution du code du bloc catch() a provoqué l’arrêt du programme (appel de System.exit(-1);),
par conséquent l’appel de Point(6,1) et les instructions après le bloc try {} n’ont pas été exécutées.
Les appels de Point(9,5) et Point(3,7) n’ont pas généré d’exceptions donc le code
du bloc catch() { } n’a pas été exécuté par conséquent l’exécution est allée
au-delà du bloc try.
Exemple:
public void Point (int x, int y) throws ErrConst {
// Déclare que le constructeur Point() peut générer une exception
if ((x <0) || (y<0)) throw new ErrConst();
// Détection de l’exception et Création d’une nouvelle valeur d’exception
this.x = x ; this.y = y; // traitement normal
}
ErrConst est une classe qui hérite de la classe Exception. Elle peut être définie de la
manière suivante:
class Point {
private int x, y;
public Point(int x, int y) throws ErrConst { // déclare une excéption
if ((x < 0) || (y < 0)) throw new ErrConst(); // déclenche une exception
this.x = x ; this.y = y;
}
public void deplace(int dx, int dy) throws ErrDepl{
if ((x+dx < 0) || (y+dy < 0)) throw new ErrDepl();
x = x+dx ; y = y+dy;
}
}
Sortie:
Erreur au point x= -2 et y=4
Erreur de Construction
ErrConst
at Point.<init>(ExceptionTestStack.java:5)
at ExceptionTestStack.main(ExceptionTestStack.java:14)
Throwable
Error
Exception
Exemple d’interfaces
public interface Figure {
public void dessineFigure();
public void deplaceFigure(int dx, int dy);
}
El Mostafa DAOUDI- p. 227
Règles
• Toutes les méthodes sont abstraites.
• Il n’y a aucun attribut.
• Une interface peut posséder des constantes
public interface NomInterface {
public static final int CONST = 2;
}
• Les interfaces ne sont pas instanciables.
I obj; // juste
I a = new I(); // Erreur
• Tout objet instance d’une classe qui implémente l’interface peut être
déclaré comme étant du type de cette interface. Supposons que la classe
ClasseA implemente l’interface I. Alors on peut avoir
I obj = new ClasseA();
• Les interfaces pourront se dériver
Dans ce cas, si on a:
Point pA=new Point(10, 32);
Alors:
System.out.println(pA) ;
affiche : abscisse = 10 ordonnée = 32
Exemple:
Integer nObj = new Integer(5);
int n = nObj.intValue();
Par exemple, pour convertir une chaîne en un entier de type int, on utilisera la
méthode statique parseInt de la classe enveloppe Integer, comme ceci :
String ch = "3587" ;
int n = Integer.parseInt(ch) ;
Par exemple:
Integer.ValueOf(uneChaine) donne le même résultat que
int n = Integer.parseInt(uneChaine);
new Integer(n) ;
Ou
Integer.parseInt(uneChaine)
Exemple:
Integer n = Integer.valueOf("12");
Double d = Double.valueOf("3.1459");
Boolean b = Boolean.valueOf("True");