Cours programamtion

publicité
Cours programmationorientée objet en Java
Chapitre I
Introduction
A) Généralités
3
Pourquoi JAVA ?
• Problème du logiciel:
• Taille
• Coût : développement et maintenance
• Fiabilité
• Solutions :
• Modularité
• Réutiliser le logiciel
• Certification
• Comment?
Historique de Java (1)
• Java a été développé à partir de décembre 1990
par une équipe de Sun Microsystems dirigée par
James Gosling
• Au départ, il s’agissait de développer un langage
de programmation pour permettre le dialogue entre
de futurs ustensiles domestiques
• Or, les langages existants tels que C++ ne sont pas à la
hauteur : recompilation dès qu'une nouvelle puce arrive,
complexité de programmation pour l'écriture de
logiciels fiables...
4
Historique de Java (2)
• 1990 : Ecriture d'un nouveau langage plus adapté à la
réalisation de logiciels embarqués, appelé OAK
• Petit, fiable et indépendant de l'architecture
• Destiné à la télévision interactive
• Non rentable sous sa forme initiale
• 1993 : le WEB « décolle », Sun redirige ce langage vers
Internet : les qualités de portabilité et de compacité du
langage OAK en ont fait un candidat parfait à une
utilisation sur le réseau. Cette réadaptation prit près de
2 ans.
• 1995 : Sun rebaptisa OAK en Java (nom de la machine à café
autour de laquelle se réunissait James Gosling et ses collaborateurs)
5
Historique de Java (3)
• Les développeurs Java ont réalisé un langage
indépendant de toute architecture de telle sorte que
Java devienne idéal pour programmer des applications
utilisables dans des réseaux hétérogènes, notamment
Internet.
• Le développement de Java devint alors un enjeu
stratégique pour Sun et l'équipe écrivit un navigateur
appelé HotJava capable d’exécuter des programmes
Java.
• La version 2.0 du navigateur de Netscape a été
développée pour supporter Java, suivi de près par
Microsoft (Internet Explorer 3)
• L'intérêt pour la technologie Java s’est accru
rapidement: IBM, Oracle et d'autres ont pris des 6
licences Java.
Les différentes versions de Java
• De nombreuses versions de Java depuis 1995
•
•
•
•
•
•
•
•
•
•
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java
1.0 en 1995
1.1 en 1996
1.2 en 1999 (Java 2, version 1.2)
1.3 en 2001 (Java 2, version 1.3)
1.4 en 2002 (Java 2, version 1.4)
5 en 2004
6 en 2006
7 en 2011
8 en 2014 celle que nous utiliserons dans nos TP
9 pour 2017 ?
• Évolution très rapide et succès du langage
• Une certaine maturité atteinte avec Java 2
• Mais des problèmes de compatibilité existaient
• entre les versions 1.1 et 1.2/1.3/1.4
• avec certains navigateurs
7
Histoire récente
• En mai 2007, Sun publie l’ensemble des outils Java dans un
« package » OpenJDK sous licence libre.
• La société Oracle a acquis en 2009 l'entreprise Sun
Microsystems. On peut désormais voir apparaître le logo
Oracle dans les documentations de l'api Java.
• Le 12 avril 2010, James Gosling, le créateur du langage de
programmation Java démissionne d’Oracle pour des motifs
qu’il ne souhaite pas divulguer. Il était devenu le directeur
technologique de la division logicielle client pour Oracle.
• Août 2012: faille de sécurité importante dans Java 7
• Mars 2014 : Java 8 met en avant plan JavaFX
8
B) Principes de base de la POO
• Objet et classe:
• Classe = définitions pour des données (variables) +
fonctions (méthodes) agissant sur ces données
• Objet = élément d’une classe (instance) avec un
état
• (une méthode ou une variable peut être
• de classe = commune à la classe ou
• d’instance = dépendant de l’instance
)
9
Principes de bases (suite)
• Encapsulation et séparation de la
spécification et de l’implémentation
• Séparer l’implémentation de la spécification.
• Ne doit être visible de l’extérieur que ce qui est
nécessaire, les détails d’implémentation sont
« cachés »
• Héritage:
• Une classe peut hériter des propriétés d’une
autre classe: un classe peut être une extension
d’une autre classe.
10
Principes de bases de la POO
• Mais surtout notion de polymorphisme:
• Si une classe A est une extension d’une classe B:
• A doit pouvoir redéfinir certaines méthodes (disons f())
• Un objet a de classe A doit pouvoir être considéré
comme un objet de classe B
• On doit donc accepter :
• B b;
• b=a; (a a toutes les propriétés d’un B)
• b.f()
• Doit appeler la méthode redéfinie dans A!
• C’est le transtypage
• (exemple: méthode paint des interfaces graphiques)
11
Principes de bases
• Polymorphisme:
• Ici l’association entre le nom ‘f()’ et le code
(code de A ou code de B) a lieu dynamiquement
(=à l’exécution)
Liaison dynamique
• On peut aussi vouloir « paramétrer » une classe
(ou une méthode) par une autre classe.
Exemple: Pile d’entiers
Dans ce cas aussi un nom peut correspondre à
plusieurs codes, mais ici l’association peut
avoir lieu de façon statique (au moment de la
compilation)
12
C) Comment assurer la
réutilisation du logiciel?
• Type abstrait de données
• définir le type par ses propriétés (spécification)
• Interface, spécification et implémentation
• Une interface et une spécification (=les
propriétés à assurer) pour définir un type
• Une (ou plusieurs) implémentation du type
abstrait de données
• Ces implémentations doivent vérifier la
spécification
13
Comment assurer la réutilisation
du logiciel?
• Pour l’utilisateur du type abstrait de données
• Accès uniquement à l’interface (pas d’accès à
l’implémentation)
• Utilisation des propriétés du type abstrait telles que
définies dans la spécification.
• (L’utilisateur est lui-même un type abstrait avec une
interface et une spécification)
14
Comment assurer la réutilisation
du logiciel?
• Mais en utilisant un type abstrait l’utilisateur
n'en connaît pas l’implémentation
• il sait uniquement que la spécification du type
abstrait est supposée être vérifiée par
l'implémentation.
• Pour la réalisation concrète, une
implémentation particulière est choisie
• Il y a naturellement polymorphisme
15
java: quelques rappels…
• Un source avec le suffixe .java
• Une classe par fichier source (en principe)
même nom pour la classe et le fichier
source (sans le suffixe .java)
• Méthode
public static void main(String argv[]);
• main est le point d’entrée
• Compilation génère un .class
• Exécution en lançant la machine java
16
Généralités…
• Un peu plus qu’un langage de programmation:
• “gratuit”!
• Indépendant de la plateforme
• Langage interprété et byte code
• Portable
• Syntaxe à la C
• Orienté objet (classes héritage)
• Nombreuses bibliothèques
• Pas de pointeurs! (ou que des pointeurs!)
• Ramasse-miettes
• Multi-thread
• Distribué (WEB) applet, servlet, portlet, etc…
17
Plateforme Java
18
• La compilation génère un .class en bytecode (langage
intermédiaire indépendant de la plateforme).
• Le bytecode est interprété par un interpréteur Java JVM
Compilation javac
interprétation java
Langage intermédiaire et
Interpréteur…
• Avantage: indépendance de la plateforme
• Échange de byte-code (applet)
• Inconvénient: efficacité
19
Plateforme Java
• La plateforme java: software au-dessus d’une
plateforme exécutable sur un hardware
(exemple MacOs, linux …)
• Java VM
• Java application Programming Interface (Java
API):
20
Tout un environnement…
• Java 8 sdk: JRE (java runtime environment + outils
de développements compilateur, debogueurs etc…)
21
Trois exemples de base
• Une application
• Une applet
• Une application avec interface graphique
22
Application:
• Fichier Appli.java:
/**
* Une application basique...
*/
class Appli {
public static void main(String[] args)
{
System.out.println("Bienvenue en
L3..."); //affichage
}
}
23
Compiler, exécuter…
• Créer un fichier Appli.java
• Compilation:
• javac Appli.java
• Création de Appli.class (bytecode)
• Interpréter le byte code:
• java Appli
• Attention aux suffixes!!!
• (il faut que javac et java soient dans $PATH)
Exception in thread "main" java.lang.NoClassDefFoundError:
• Il ne trouve pas le main -> vérifier le nom!
• Variable CLASSPATH ou option -classpath
24
Remarques
• Commentaires /* … */ et //
• Définition de classe
• une classe contient des méthodes (=fonctions) et des
variables
• Pas de fonctions ou de variables globales (uniquement
dans des classes ou des instances)
• Méthode main:
• public static void main(String[] arg)
•
•
•
•
public
static
Void
String
• Point d’entrée
25
Remarques
• Classe System
• out est une variable de la classe System
• println méthode de System.out
• out est une variable de classe qui fait référence à
une instance de la classe PrintStream qui
implémente un flot de sortie.
• Cette instance a une méthode println
26
Remarques…
• Classe: définit des méthodes et des
variables (déclaration)
• Instance d’une classe (objet)
• Méthode de classe: fonction associée à (toute
la) classe.
• Méthode d’instance: fonction associée à une
instance particulière.
• Variable de classe: associée à une classe
(globale et partagée par toutes les instances)
• Variable d’instance: associée à un objet
(instancié)
• Patience…
27
Applet:
• Applet et WEB
• Client (navigateur) et serveur WEB
• Le client fait des requêtes html, le serveur
répond par des pages html
• Applet:
• Le serveur répond par une page contenant des
applets
• Applet: byte code
• Code exécuté par le client
• Permet de faire des animations avec interfaces
graphiques sur le client.
• Une des causes du succès de java.
28
Exemple applet
• Fichier MonApplet.java:
/**
* Une applet basique...
*/
import java.applet.Applet;
import java.awt.Graphics;
public class MonApplet extends Applet {
public void paint(Graphics g){
g.drawString("Bienvenue en en L3...",
50,25);
}
}
29
Remarques:
• import et package:
• Un package est un regroupement de
classes.
• Toute classe est dans un package
• Package par défaut (sans nom)
• classpath
• import java.applet.*;
• Importe le package java.applet
• Applet est une classe de ce package,
• Sans importation il faudrait java.applet.Applet
30
Remarques:
• La classe Applet contient ce qu’il faut pour
écrire une applet
• … extends Applet:
• La classe définie est une extension de la classe
Applet:
• Elle contient tout ce que contient la classe Applet
• (et peut redéfinir certaines méthodes (paint))
• Patience!!
31
Remarques…
32
• Une Applet contient les méthodes paint start et
init. En redéfinissant paint, l’applet une fois lancée
exécutera ce code redéfini.
• Graphics g argument de paint est un objet qui
représente le contexte graphique de l’applet.
• drawString est une méthode (d’instance) qui affiche une
chaîne,
• 50, 25: affichage à partir de la position (x,y) à partir du point
(0,0) coin en haut à gauche de l’applet.
Pour exécuter l’applet
• L’applet doit être exécutée dans un navigateur
capable d’interpréter du bytecode
correspondant à des applet.
• Il faut créer un fichier HTML pour le
navigateur.
33
Html pour l’applet
34
• Fichier Bienvenu.html:
<HTML>
<HEAD>
<TITLE> Une petite applet </TITLE>
<BODY>
<APPLET CODE='MonApplet.class' WIDTH=200 Height=50>
</APPLET>
</BODY>
</HTML>
Html
35
• Structure avec balises:
• Exemples:
• <HTML> </HTML>
• url:
• <a target="_blank"
href="http://wwww.tondeurh.fr">page de TH</a>
• Ici:
<APPLET CODE='MonApplet.class' WIDTH=200 Height=50>
</APPLET>
Exemple interface graphique
Fichier MonSwing.java:
/**
* Une application
basique... avec interface graphique
*/
import javax.swing.*;
public class MonSwing {
private static void creerFrame() {
//Une formule magique...
JFrame.setDefaultLookAndFeelDecorated(true);
//Creation d'une Frame
JFrame frame = new JFrame("MonSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Afficher un message
JLabel label = new JLabel("Bienvenue en L3...");
frame.getContentPane().add(label);
//Afficher la fenêtre
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
creerFrame();
}
}
36
Remarques
• Importation de packages
• Définition d’un conteneur top-level JFrame,
implémenté comme instance de la classe JFrame
• Affichage de ce conteneur
• Définition d’un composant JLabel, implémenté
comme instance de JLabel
• Ajout du composant JLabel dans la JFrame
• Définition du comportement de la Jframe sur un
click du bouton de fermeture
• Une méthode main qui crée la JFrame
37
Chapitre II
Syntaxe du langage Java
Les commentaires
• /* commentaire sur une ou plusieurs lignes */
• Identiques à ceux existant dans le langage C
• // commentaire de fin de ligne
• Identiques à ceux existant en C++
• /** commentaire d'explication */
• Les commentaires d'explication se placent
généralement juste avant une déclaration
(d'attribut ou de méthode)
• Ils sont récupérés par l'utilitaire javadoc et
inclus dans la documentation ainsi générée.
39
Instructions, blocs et blancs
• Les instructions Java se terminent par un ;
• Les blocs sont délimités par :
{ pour le début de bloc
} pour la fin du bloc
Un bloc permet de définir un regroupement
d’instructions. La définition d’une classe ou d’une
méthode se fait dans un bloc.
• Les espaces, tabulations, sauts de ligne sont
autorisés. Cela permet de présenter un code
40
plus lisible.
Point d’entrée d’un programme
Java
• Pour pouvoir faire un programme exécutable
il faut toujours une classe qui contienne une
méthode particulière, la méthode « main »
• c’est le point d’entrée dans le programme : le
microprocesseur sait qu’il va commencer à
exécuter les instructions à partir de cet endroit
public static void main(String arg[ ])
{
…/…
}
41
Exemple (1)
Fichier Bonjour.java
public class Bonjour
{ //Accolade débutant la classe Bonjour
La classe est l’unité de
base de nos programmes.
Le mot clé en Java pour
définir une classe est
class
public static void main(String args[])
{ //Accolade débutant la méthode main
/* Pour l’instant juste une instruction */
System.out.println(“bonjour”);
} //Accolade fermant la méthode main
} //Accolade fermant la classe Bonjour
42
Exemple (2)
Fichier Bonjour.java
public class Bonjour
Accolades délimitant le
début et la fin de la définition
de la class Bonjour
{
public static void main(String args[])
{
System.out.println(“bonjour”);
Accolades délimitant le début
et la fin de la méthode main
}
}
Les instructions se terminent
par des ;
43
Exemple (3)
Fichier Bonjour.java
public class Bonjour
{
Une méthode peut recevoir
des paramètres. Ici la méthode
main reçoit le paramètre args
qui est un tableau de chaîne
de caractères.
public static void main(String args[])
{
System.out.println(“bonjour”);
}
}
44
Compilation et exécution (1)
Le nom du fichier est nécessairement
celui de la classe avec l’extension
.java en plus. Java est sensible à la
casse des lettres.
Fichier Bonjour.java
Compilation en bytecode
java dans une console DOS:
javac Bonjour.java
Génère un fichier
Bonjour.class
Exécution du programme
(toujours depuis la console
DOS) sur la JVM :
java Bonjour
Affichage de « bonjour »
dans la console
public class Bonjour
{
public static void main(String[] args)
{
System.out.println(“bonjour”);
}
}
45
Compilation et exécution (3)
• Pour résumer, dans une console DOS, si j’ai un
fichier Bonjour.java pour la classe Bonjour :
• javac Bonjour.java
• Compilation en bytecode java
• Indication des erreurs de syntaxe éventuelles
• Génération d’un fichier Bonjour.class si pas d’erreurs
• java Bonjour
• Java est la machine virtuelle
• Exécution du bytecode
• Nécessité de la méthode main, qui est le point
d’entrée dans le programme
46
Identificateurs (1)
• On a besoin de nommer les classes, les variables,
les constantes, etc. ; on parle d’identificateur.
• Les identificateurs commencent par
une lettre, _ ou $
Attention : Java distingue les majuscules des
minuscules
• Conventions sur les identificateurs :
• Si plusieurs mots sont accolés, mettre une majuscule
à chacun des mots sauf le premier.
• exemple : uneVariableEntiere
• La première lettre est majuscule pour les classes et
47
les interfaces
• exemples : MaClasse, UneJolieFenetre
Identificateurs (2)
• Conventions sur les identificateurs :
• La première lettre est minuscule pour les
méthodes, les attributs et les variables
• exemples : setLongueur, i, uneFenetre
• Les constantes sont entièrement en
majuscules
• exemple : LONGUEUR_MAX
48
Les mots réservés de Java
abstract
default
goto
null
synchronized
boolean
do
if
package
this
break
double
implements
private
throw
byte
else
import
protected
throws
case
extends
instanceof
public
transient
catch
false
int
return
true
char
final
interface
short
try
class
finally
long
static
void
continue
float
native
super
volatile
const
for
new
switch
while 49
Les types de bases (1)
• En Java, tout est objet sauf les types de base.
• Il y a huit types de base :
• un type booléen pour représenter les variables ne pouvant prendre
que 2 valeurs (vrai et faux, 0 ou 1, etc.) : boolean avec les valeurs
associées true et false
• un type pour représenter les caractères : char
• quatre types pour représenter les entiers de divers taille : byte,
short, int et long
• deux types pour représenter les réelles : float et double
• La taille nécessaire au stockage de ces types est
indépendante de la machine.
• Avantage : portabilité
• Inconvénient : "conversions" coûteuses
50
Les types de bases (2) : les
entiers
• Les entiers (avec signe)
• byte : codé sur 8 bits, peuvent représenter
des entiers allant de -27 à 27 –1 (-128 à
+127)
• short : codé sur 16 bits, peuvent
représenter des entiers allant de
-215 à
215 –1
• int : codé sur 32 bits, peuvent représenter
des entiers allant de -231 à 231 –1
• long : codé sur 64 bits, peuvent représenter
51
des entiers allant de -263 à 263 –1
Les types de bases (3) : les
entiers
• Notation
•
•
•
•
2 entier normal en base décimal
2L entier au format long en base décimal
010 entier en valeur octale (base 8)
0xF entier en valeur hexadécimale (base 16)
• Opérations sur les entiers
• opérateurs arithmétiques +, -, *
• / :division entière si les 2 arguments sont des
entiers
• % : reste de la division entière
• exemples :
• 15 / 4 donne 3
• 15 % 2 donne 1
52
Les types de bases (4) : les entiers
• Opérations sur les entiers (suite)
• les opérateurs d’incrémentation ++
et de décrémentation et -• ajoute ou retranche 1 à une variable
int n = 12;
n ++; //Maintenant n vaut 13
• n++; « équivalent à » n = n+1;
n--; « équivalent à » n = n-1;
• 8++; est une instruction illégale
• peut s’utiliser de manière suffixée : ++n. La différence avec la
version préfixée se voit quand on les utilisent dans les expressions.
En version suffixée la (dé/inc)rémentation s’effectue en premier
int m=7; int n=7;
int a=2 * ++m; //a vaut5316, m vaut 8
int b=2 * n++; //b vaut 14, n vaut 8
Les types de bases (5) : les réels
• Les réels
• float : codé sur 32 bits, peuvent
représenter des nombres allant de -1035 à
+ 1035
• double : codé sur 64 bits, peuvent
représenter des nombres allant de -10400 à
+10400
• Notation
• 4.55 ou 4.55D réel double précision
54
• 4.55f réel simple précision
Les types de bases (6) : les réels
• Les opérateurs
• opérateurs classiques +, -, *, /
• attention pour la division :
• 15 / 4 donne 3 division entière
• 15 % 2 donne 1
• 11.0 / 4 donne 2.75
(si l’un des termes de la division est un
réel, la division retournera un réel).
• puissance : utilisation de la méthode pow
de la classe Math.
55 à
• double y = Math.pow(x, a) équivalent
x^a, x et a étant de type double
Les types de bases (7) : les
booléens
• Les booléens
• boolean
contient soit vrai (true) soit faux (false)
• Les opérateurs logiques de
comparaisons
• Egalité : opérateur ==
• Différence : opérateur !=
• supérieur et inférieur strictement à :
opérateurs > et <
• supérieur et inférieur ou égal :
56
opérateurs >= et <=
Les types de bases (8) : les
booléens
• Notation
boolean x;
x= true;
x= false;
x= (5==5); // l ’expression (5==5) est évaluée et la valeur
est affectée à x qui vaut alors vrai
x= (5!=4); // x vaut vrai, ici on obtient vrai si 5 est différent de 4
x= (5>5); // x vaut faux, 5 n'est pas supérieur strictement à 5
x= (5<=5); // x vaut vrai, 5 est bien inférieur ou égal à 5
57
Les types de bases (9) : les
booléens
• Les autres opérateurs logiques
•
•
•
•
et logique : &&
ou logique : ||
non logique : !
Exemples : si a et b sont 2 variables booléennes
boolean a,b, c;
a= true;
b= false;
c= (a && b); // c vaut false
c= (a || b); // c vaut true
58
c= !(a && b); // c vaut true
c=!a; // c vaut false
Les types de bases (10) : les
caractères
• Les caractères
• char : contient une seule lettre
• le type char désigne des caractères en
représentation Unicode
• Codage sur 2 octets contrairement à
ASCII/ANSI codé sur 1 octet. Le codage
ASCII/ANSI est un sous-ensemble d’Unicode
• Notation hexadécimale des caractères Unicode
de ‘ \u0000 ’ à ‘ \uFFFF ’.
• Plus d’information sur Unicode à :
www.unicode.org
59
Les types de bases (11) : les
caractères
• Notation
char a,b,c; // a,b et c sont des variables du type
char
a='a'; // a contient la lettre 'a'
b= '\u0022' //b contient le caractère guillemet : "
c=97; // x contient le caractère de rang 97 : 'a'
60
Les types de bases (12)
exemple et remarque
int x = 0, y = 0;
float z = 3.1415F;
double w = 3.1415;
long t = 99L;
boolean test = true;
char c = 'a';
• Remarque importante :
• Java exige que toutes les variables soient
définies et initialisées. Le compilateur sait
déterminer si une variable est susceptible d'être
utilisée avant initialisation et produit une erreur
de compilation.
61
Les structures de contrôles (1)
• Les structures de contrôle
classiques existent en Java :
• if, else
• switch, case, default, break
• for
• while
• do, while
62
Les structures de contrôles (2) :
if / else
• Instructions conditionnelles
• Effectuer une ou plusieurs instructions seulement si
une certaine condition est vraie
if (condition) instruction;
et plus généralement : if (condition)
{ bloc d’instructions}
condition doit être un booléen ou renvoyer une valeur booléenne
• Effectuer une ou plusieurs instructions si une certaine
condition est vérifiée sinon effectuer d’autres
instructions
if (condition) instruction1; else instruction2;
63
et plus généralement if (condition) { 1er bloc
d’instructions} else {2ème bloc d’instruction}
Les structures de contrôles (3) :
if / else
Max.java
import java.io.*;
public class Max
{
public static void main(String args[])
{
Console console = System.console();
int nb1 = Integer.parseInt(console.readLine("Entrer un entier:"));
int nb2 = Integer.parseInt(console.readLine("Entrer un autre entier:"));
if (nb1 > nb2)
System.out.println("l'entier le plus grand est "+ nb1);
else
System.out.println("l'entier le plus grand est "+ nb2);
}
64
}
Les structures de contrôles (4) :
while
• Boucles indéterminées
• On veut répéter une ou plusieurs instructions un
nombre indéterminés de fois : on répète
l’instruction ou le bloc d’instruction tant que une
certaine condition reste vraie
• nous avons en Java une première boucle while (tant
que)
• while (condition) {bloc d’instructions}
• les instructions dans le bloc sont répétées tant
que la condition reste vraie.
• On ne rentre jamais dans la boucle si la
65
condition est fausse dès le départ
Les structures de contrôles (5) :
while
• Boucles indéterminées
• un autre type de boucle avec le while:
• do {bloc d’instructions} while (condition)
• les instructions dans le bloc sont répétées
tant que la condition reste vraie.
• On rentre toujours au moins une fois dans
la boucle : la condition est testée en fin
de boucle.
66
Les structures de contrôles (6) :
while
Facto1.java
import java.io.*;
public class Facto1
{
public static void main(String args[])
{
int n, result,i;
n = Integer.parseInt(System.console().readLine("Entrer une valeur pour n:"));
result = 1; i = n;
while (i > 1)
{
result = result * i;
i--;
}
67
System.out.println("la factorielle de "+n+" vaut "+result);
}
}
Les structures de contrôles (7) :
for
• Boucles déterminées
• On veut répéter une ou plusieurs instructions un nombre
déterminés de fois : on répète l’instruction ou le bloc
d’instructions pour un certain nombre de pas.
• La boucle for
for (int i = 1; i <= 10; i++)
System.out.println(i); //affichage des nombres de 1 à 10
• une boucle for est en fait équivalente à une boucle while
for (instruction1; expression1; expression2) {bloc}
… est équivalent à …
instruction 1; while (expression1) {bloc; expression2}}
68
Les structures de contrôles (8) :
for
Facto2.java
import java.io.*;
public class Facto2
{
public static void main(String args[])
{
int n, result,i;
n = Integer.parseInt(System.console().readLine("Entrer une valeur pour n:"));
result = 1;
for(i =n; i > 1; i--)
{
result = result * i;
}
System.out.println("la factorielle de "+n+" vaut "+result);
69
}
}
Les structures de contrôles (9) :
switch
• Sélection multiples
• l’utilisation de if / else peut s’avérer lourde quand on doit
traiter plusieurs sélections et de multiples alternatives
• pour cela existe en Java le switch / case assez identique à
celui de C/C++
• La valeur sur laquelle on teste doit être un char ou un
entier (à l’exclusion d’un long).
• L’exécution des instructions correspondant à une
alternative commence au niveau du case correspondant et
se termine à la rencontre d’une instruction break ou
arrivée à la fin du switch
70
Les structures de contrôles (10)
: switch
Alternative.java
import java.io.*;
Variable contenant la valeur
que l’on veut tester.
public class Alternative
Première alternative :
{
on affiche Un et on sort
public static void main(String args[])
du bloc du switch au break;
{
int nb = Integer.parseInt(System.console().readLine("Entrer une valeur pour n:"));
switch(nb)
{
Deuxième alternative :
case 1:
on affiche Deux et on sort
System.out.println("Un"); break;
du bloc du switch au break;
case 2:
System.out.println("Deux"); break;
default:
Alternative par défaut:
System.out.println("Autre nombre"); break;
on réalise une action
}
71
par défaut.
}
}
Les tableaux (1)
• Les tableaux permettent de stocker plusieurs
valeurs de même type dans une variable.
• Les valeurs contenues dans la variable sont repérées
par un indice
• En langage java, les tableaux sont des objets
• Déclaration
• int tab [ ];
String chaines[ ];
• Création d'un tableau
• tab = new int [20]; // tableau de 20 int
• chaines = new String [100]; // tableau de 100 chaine
72
Les tableaux (2)
• Le nombre d'éléments du tableau est
mémorisé. Java peut ainsi détecter à
l'exécution le dépassement d'indice et générer
une exception. Mot clé length
• Il est récupérable par nomTableau.length
int taille = tab.length; //taille vaut 20
• Comme en C/C++, les indices d’un tableau
commencent à ‘ 0 ’. Donc un tableau de taille
100 aura ses indices qui iront de 0 à 99.
73
Les tableaux (3)
• Initialisation
tab[0]=1;
tab[1]=2; //etc.
noms[0] = new String( "Boule");
noms[1] = new String( "Bill");//etc
• Création et initialisation simultanées
String noms [ ] = {"Boule","Bill"};
Point pts[ ] = { new Point (0, 0), new Point (10, -1)};
74
Les tableaux (4)
Tab1.java
public class Tab1
{
public static void main (String args[])
{
int tab[ ] ;
tab = new int[4];
tab[0]=5;
tab[1]=3;
tab[2]=7;
tab[3]=tab[0]+tab[1];
}
}
Les indices vont toujours
de 0 à (taille-1)
Pour déclarer une variable tableau
on indique le type des éléments du
tableau et le nom de la variable
tableau suivi de [ ]
on utilise new <type> [taille];
pour initialiser le tableau
On peut ensuite affecter
des valeurs au
différentes cases du
tableau :
<nom_tableau>[indice]75
Les tableaux (5)
Tab1.java
public class Tab1
{
public static void main (String args[])
{
int tab[ ] ;
tab = new int[4];
tab[0]=5;
tab[1]=3;
tab[2]=7;
tab[3]=tab[0]+tab[1];
}
}
Mémoire
0x0000
0x258
0
0
0
0
76
Les tableaux (6)
Tab1.java
public class Tab1
{
public static void main (String args[])
{
int tab[ ] ;
tab = new int[4];
tab[0]=5;
tab[1]=3;
tab[2]=7;
tab[3]=tab[0]+tab[1];
}
}
Mémoire
0x258
5
0
0
3
0
7
0
8
77
Les tableaux (7)
Tab2.java
public class Tab2
{
public static void main (String args[])
{
String tab[ ] ;
tab = new String[4];
tab[0]=new String("Pierre");
tab[1]=new String("Paul");
tab[2]=new String("Jacques");
tab[3]=new String("Philippe");
}
}
Mémoire
0x0258
0x0106
0x0116
0x0126
0x0136
"Pierre"
"Paul"
"Jacques"
"Philippe"
78
La classe String (1)
• Attention ce n’est pas un type de base. Il s'agit d'une
classe défini dans l’API Java (Dans le package
java.lang)
String s="aaa"; // s contient la chaîne "aaa" mais
String s=new String("aaa"); // identique à la ligne précédente
• La concaténation
• l’opérateur + entre 2 String les concatène :
String str1 = "Bonjour ! ";
String str2 = null;
str2 = "Comment vas-tu ?";
String str3 = str1 + str2; / * Concaténation de chaînes : str3
contient " Bonjour ! Comment vas-tu ?"
79
Différences entre objets et
types de base
Mémoire
int x=3,y=3;
x == y est vrai
3
3
0x768
0x852
String s1="abc",s2="abc";
s1 == s2 est faux...
Abc
....
Quand on compare 2 variables d’un type de base
on compare leur valeur. Quand on compare 2 objet
avec les opérateurs on compare leur référence (leur
adresse en mémoire). Introduction de la méthode
equals() pour les objets : s1.equals(s2) est vrai
Abc
....
80
La classe String (2)
• Longueur d’un objet String :
• méthode int length() : renvoie la longueur de la chaîne
String str1 = "bonjour";
int n = str1.length(); // n vaut 7
• Sous-chaînes
• méthode String substring(int debut, int fin)
• extraction de la sous-chaine depuis la position debut
jusqu’à la position fin non-comprise.
String str2 = str1.substring(0,3); // str2 contient la valeur "bon"
• le premier caractère d’une chaîne occupe la position 0
• le deuxième paramètre de substring indique la position du
premier caractère que l ’on ne souhaite pas copier
81
La classe String (3)
• Récupération d’un caractère dans une chaîne
• méthode char charAt(int pos) : renvoie le caractère situé à
la position pos dans la chaîne de caractère à laquelle on
envoie se message
String str1 = "bonjour";
char unJ = str1.charAt(3); // unJ contient le caractère 'j'
• Modification des objets String
• Les String sont inaltérables en Java : on ne peut modifier
individuellement les caractères d’une chaîne.
• Par contre il est possible de modifier le contenu de la
variable contenant la chaîne (la variable ne référence plus
la même chaîne).
str1 = str1.substring(0,3) + " soir"; /* str1 contient
maintenant la chaîne "bonsoir" */
82
La classe String (4)
• Les chaînes de caractères sont des objets :
• pour tester si 2 chaînes sont égales il faut utiliser la
méthode boolean equals(String str) et non ==
• pour tester si 2 chaînes sont égales à la casse près il faut
utiliser la méthode boolean equalsIgnoreCase(String str)
String str1 = "BonJour";
String str2 = "bonjour"; String str3 = "bonjour";
boolean a, b, c, d;
a = str1.equals("BonJour"); //a contient la valeur true
b = (str2 = = str3); //b contient la valeur false
c = str1.equalsIgnoreCase(str2);//c contient la valeur true
d = "bonjour".equals(str2); //d contient la valeur true
83
La classe String (5)
• Quelques autres méthodes utiles
• boolean startsWith(String str) : pour tester si une chaine de
caractère commence par la chaine de caractère str
• boolean endsWith(String str) : pour tester si une chaîne de
caractère se termine par la chaine de caractère str
String str1 = "bonjour ";
boolean a = str1.startsWith("bon");//a vaut true
boolean b = str1.endsWith("jour");//b vaut true
84
La classe String (7)
Plus d’informations
dans les
documentations
de l’API dans le
package
java.lang
85
Chapitre III
Classes et objets
Concept d’objet
• Qu’est-ce qu’un objet ?
• Le monde qui nous entoure est composé d'objets
• Ces objets ont tous deux caractéristiques
• un état
• un comportement
• Exemples d’objets du monde réel
• chien
• état : nom, couleur, race, poids....
• comportement : manger,aboyer,renifler...
• Bicyclette
• état : nombre de vitesses, vitesse courante, couleur
• comportement : tourner, accélérer, changer de vitesse
87
L’approche objet
• L’approche objet :
• Programmation dirigé par les données et non par les traitements
• les procédures existent toujours mais on se concentre d’abord sur les
entités que l’on va manipuler avant de se concentrer sur la façon
dont on va les manipuler
• Notion d’encapsulation
• les données et les procédures qui les manipulent (on parle de
méthodes) sont regroupés dans une même entité (la classe).
• Un objet informatique
• maintient son état dans des variables (appelées champs)
• implémente son comportement à l'aide de méthodes
objet informatique = regroupement logiciel de variables et de méthodes
• Cycle de vie
• construction (en mémoire)
• Utilisation (changements d’état par affectations, comportements par
88
exécution de méthodes)
• destruction
Concept de classe
• En informatique, la classe est un modèle décrivant les
caractéristiques communes et le comportement d’un
ensemble d’objets : la classe est un moule et l’objet est
ce qui est moulé à partir de cette classe
• Mais l'état de chaque objet est indépendant des autres
• Les objets sont des représentations dynamiques (appelées
instances) du modèle défini au travers de la classe.
• Une classe permet d’instancier plusieurs objets.
• Chaque objet est instance d’une seule classe.
89
La classe (1) : définition
• Classe : description d’une famille d’objets ayant une
même structure et un même comportement. Elle est
caractérisée par :
• Un nom
• Une composante statique : des champs (ou attributs)
nommés ayant une valeur. Ils caractérisent l’état des objets
pendant l’exécution du programme
• Une composante dynamique : des méthodes représentant le
comportement des objets de cette classe. Elles manipulent
les champs des objets et caractérisent les actions pouvant
être effectuées par les objets.
90
La classe (2) : représentation
graphique
Nom
Champs
Méthodes
Une classe représentée avec la notation
UML (Unified Modeling Language)
91
Syntaxe de définition d’une classe
Exemple : Une classe définissant un point
Class Point
Nom de la Classe
{
double x; // abscisse du point
Attributs
double y; // ordonnée du point
// translate de point de (dx,dy)
void translate (double dx, double dy) {
x = x+dx;
y = y+dy;
Méthodes
}
// calcule la distance du point à l’origine
double distance() {
return Math.sqrt(x*x+y*y);
}
}
92
L’instanciation (1)
• Instanciation : concrétisation d’une classe en un objet
« concret ».
• Dans nos programmes Java nous allons définir des classes et
instancier ces classes en des objets qui vont interagir. Le
fonctionnement du programme résultera de l’interaction entre ces
objets « instanciés ».
• En Programmation Orientée Objet, on décrit des classes et
l’application en elle-même va être constituée des objets instanciés,
à partir de ces classes, qui vont communiquer et agir les uns sur les
autres.
93
L’instanciation (2)
• Instance
• représentant physique d'une classe
• obtenu par moulage du dictionnaire des variables et détenant les
valeurs de ces variables.
• Son comportement est défini par les méthodes de sa classe
• Par abus de langage « instance » = « objet »
• Exemple :
• si nous avons une classe voiture, alors votre voiture est une
instance particulière de la classe voiture.
• Classe = concept, description
• Objet = représentant concret d’une classe
94
Les constructeurs (1)
• L'appel de new pour créer un nouvel objet déclenche, dans
l'ordre :
• L'allocation mémoire nécessaire au stockage de ce nouvel objet et
l'initialisation par défaut de ces attributs,
• L'initialisation explicite des attributs, s'il y a lieu,
• L'exécution d'un constructeur.
• Un constructeur est une méthode d'initialisation.
public class Application
{
public static void main(String args[])
{
Personne jean = new Personne();
jean.setNom("Jean") ;
} }
Le constructeur est ici celui
par défaut (pas de
constructeur défini dans
la classe Personne)
95
Les constructeurs (2)
• Lorsque l'initialisation explicite n'est pas possible (par
exemple lorsque la valeur initiale d'un attribut est
demandée dynamiquement à l'utilisateur), il est possible
de réaliser l'initialisation au travers d'un constructeur.
• Le constructeur est une méthode :
• de même nom que la classe,
• sans type de retour.
• Toute classe possède au moins un constructeur. Si le
programmeur ne l'écrit pas, il en existe un par défaut,
sans paramètres, de code vide.
96
Les constructeurs (3)
Personne.java
public class Personne
{
public String nom;
public String prenom;
public int age;
public Personne(String unNom,
String unPrenom,
int unAge)
{
nom=unNom;
prenom=unPrenom;
age = unAge;
}
}
Va donner une erreur à la compilation
Définition d’un
Constructeur. Le
constructeur par défaut
(Personne() )n’existe plus.
Le code précédent occasionnera
une erreur
public class Application
{
public static void main(String
args[])
{
Personne jean = new Personne();
jean.setNom("Jean") ;
} }
97
Les constructeurs (4)
• Pour une même classe, il peut y avoir plusieurs
constructeurs, de signatures différentes (surcharge).
• L'appel de ces constructeurs est réalisé avec le mot
new auquel on fait passer les paramètres.
• p1 = new Personne(« Hervé", « Tondeur", 44);
• Déclenchement du "bon" constructeur
• Il se fait en fonction des paramètres passés lors de l'appel
(nombre et types). C'est le mécanisme de "lookup".
• Attention
• Si le programmeur crée un constructeur (même si c'est un
constructeur avec paramètres), le constructeur par98défaut
n'est plus disponible. Attention aux erreurs de compilation !
Les constructeurs (5)
Personne.java
public class Personne
{
public String nom;
public String prenom;
public int age;
public void Personne()
{
nom=null; prenom=null;
age = 0;
}
public String Personne(String unNom,
String unPrenom, int unAge)
{
nom=unNom;
prenom=unPrenom; age = unAge;
} }
Redéfinition d’un
Constructeur sans paramètres
On définit plusieurs constructeurs
qui se différencient uniquement
par leurs paramètres (on parle
de leur signature)
99
Classe et objet en Java
Du modèle à …
… la classe Java et
de la classe à ...
... des instances
de cette classe
class Personne
Personne jean, pierre;
{
jean = new Personne ();
String nom;
pierre = new Personne ();
int age;
float salaire;
}
L’opérateur d’instanciation en Java est new :
MaClasse monObjet = new MaClasse();
En fait, new va réserver l’espace mémoire nécessaire pour créer l’objet
« monObjet » de la classe « MaClasse »
Le new ressemble beaucoup au malloc du C
100
Accès aux attributs d’un objet (1)
Personne.java
public class Personne
{
public String nom;
public String prenom;
public int age;
public void setNom(String unNom)
{
nom = unNom;
}
public String getNom()
{
return (nom);
}
}
101
Accès aux attributs d’un objet (2)
Application.java
public class Application
{
public static void main(String args[])
{
Personne jean = new Personne()
jean.nom = "Jean" ;
jean.prenom = "Pierre" ;
}
}
Remarque :
Contrairement aux variables, les attributs d'une classe, s'ils ne sont pas
initialisés, se voient affecter automatiquement une valeur par défaut.
Cette valeur vaut : 0 pour les variables numériques, false pour les booléens,
et null pour les références.
102
Accès aux méthodes d’un objet (1)
Personne.java
public class Personne
{
public String nom;
public String prenom;
public int age;
public void setNom(String unNom)
{
nom = unNom;
}
public String getNom()
{
return (nom);
}
}
103
Accès aux méthodes d’un objet (2)
Application.java
public class Application
{
public static void main(String args[])
{
Personne jean = new Personne()
jean.setNom("Jean") ;
}
}
104
Notion de méthodes et de
paramètres (1)
La notion de méthodes dans les langages objets
• Proches de la notion de procédure ou de fonction dans
les langages procéduraux.
• La méthode c’est avant tout le regroupement d’un
ensemble d’instructions suffisamment générique pour
pouvoir être réutilisées
• Comme pour les procédures ou les fonctions (au sens
mathématiques) on peut passer des paramètres aux
méthodes et ces dernières peuvent renvoyer des valeurs
(grâce au mot clé return).
105
Mode de passage des paramètres
• Java n'implémente qu'un seul mode de passage des
paramètres à une méthode : le passage par valeur.
• Conséquences :
• l'argument passé à une méthode ne peut être modifié,
• si l'argument est une instance, c'est sa référence qui est
passée par valeur. Ainsi, le contenu de l'objet peut être
modifié, mais pas la référence elle-même.
106
Notion de méthodes et de paramètres (2)
exemple : public,
static
type de la valeur
renvoyée ou void
couples d'un type et d'un
identificateur séparés par des
«,»
<modificateur> <type-retour> <nom> (<liste-param>) {<bloc>}
public double add (double number1, double number2)
{
return (number1 +number2);
}
Notre méthode
retourne ici une
valeur
107
Portée des variables (1)
• Les variables sont connues et ne sont connues qu’à
l’intérieur du bloc dans lequel elles sont déclarées
public class Bidule
{
int i, j, k;
public void truc(int z)
{
int j,r;
r = z;
}
public void machin()
{
k = r;
}
}
Ce sont 2 variables différentes
k est connu au niveau de la méthode
machin() car déclaré dans le bloc de la
classe. Par contre r n’est pas défini pour
machin(). On obtient une erreur à la
compilation
108
Portée des variables (2)
• En cas de conflit de nom entre des variables locales
et des variables globales, c’est toujours la variable la
plus locale qui est considérée comme étant la
variable désignée par cette partie du programme
• Attention par conséquent à ce type de conflit quand on
manipule des variables globales.
public class Bidule
{
int i, k, j;
public void truc(int z)
{
int j,r;
j = z;
}
C’est le j défini en local
qui est utilisé dans
la méthode truc()
}
109
Destruction d’objets (1)
• Java n'a pas repris à son compte la notion de destructeur
telle qu’elle existe en C++ par exemple.
• C'est le ramasse-miettes (ou Garbage Collector - GC en
anglais) qui s'occupe de collecter les objets qui ne sont
plus référencés.
• Le ramasse-miettes fonctionne en permanence dans un
thread de faible priorité (en « tâche de fond »). Il est
basé sur le principe du compteur de références.
110
Destruction d’objets (2)
• Ainsi, le programmeur n’a plus à gérer directement la
destruction des objets, ce qui était une importante
source d'erreurs (on parlait de fuite de mémoire ou
« memory leak » en anglais).
• Le ramasse-miettes peut être "désactivé" en lançant
l'interpréteur java avec l'option -noasyncgc.
• Inversement, le ramasse-miettes peut être lancé par une
application avec l'appel System.gc();
111
Destruction d’objets (3)
• Il est possible au programmeur d'indiquer ce qu'il faut
faire juste avant de détruire un objet.
• C'est le but de la méthode finalize() de l'objet.
• Cette méthode est utile, par exemple, pour :
•
•
•
•
fermer une base de données,
fermer un fichier,
couper une connexion réseau,
etc.
112
L’encapsulation (1)
• Notion d'encapsulation :
• les données et les procédures qui les manipulent sont
regroupées dans une même entité, l'objet.
• Les détails d'implémentation sont cachés, le monde extérieur
n'ayant accès aux données que par l'intermédiaire d'un
ensemble d'opérations constituant l'interface de l'objet.
• Le programmeur n'a pas à se soucier de la représentation
physique des entités utilisées et peut raisonner en termes
d'abstractions.
113
L’encapsulation (2)
• Programmation dirigée par les données :
• pour traiter une application, le programmeur commence par
définir les classes d'objets appropriées, avec leurs opérations
spécifiques.
• chaque entité manipulée dans le programme est un représentant
(ou instance) d'une de ces classes.
• L'univers de l'application est par conséquent composé d'un
ensemble d'objets qui détiennent, chacun pour sa part, les clés
de leur comportement.
114
Contrôle d’accès (1)
• Chaque attribut et chaque méthode d'une classe peut
être :
• visible depuis les instances de toutes les classes d'une
application. En d'autres termes, son nom peut être utilisé
dans l'écriture d'une méthode de ces classes. Il est alors
public.
• visible uniquement depuis les instances de sa classe. En
d'autres termes, son nom peut être utilisé uniquement dans
l'écriture d'une méthode de sa classe. Il est alors privé.
• Les mots réservés sont :
• public
• private
115
Contrôle d’accès (2)
• En toute rigueur, il faudrait toujours que :
• les attributs ne soient pas visibles,
• Les attributs ne devraient pouvoir être lus ou modifiés que
par l'intermédiaire de méthodes prenant en charge les
vérifications et effets de bord éventuels.
• les méthodes "utilitaires" ne soient pas visibles,
• seules les fonctionnalités de l'objet, destinées à être
utilisées par d'autres objets soient visibles.
• C’est la notion d’encapsulation
• Nous verrons dans la suite que l’on peut encore
affiner le contrôle d’accès
116
Contrôle d’accès (3)
public class Parallelogramme
{
private int longueur = 0; // déclaration + initialisation explicite
private int largeur = 0; // déclaration + initialisation explicite
public int profondeur = 0; // déclaration + initialisation explicite
public void affiche ( )
{System.out.println("Longueur= " + longueur + " Largeur = " + largeur +
" Profondeur = " + profondeur);
}}
public class ProgPpal
{
public static void main(String args[])
{
Parallelogramme p1 = new Parallelogramme();
p1.longueur = 5;
// Invalide car l'attribut est privé
p1.profondeur = 4; // OK
p1.affiche( );
// OK
}}
117
Variables de classe (1)
• Il peut s'avérer nécessaire de définir un attribut
dont la valeur soit partagée par toutes les
instances d'une classe. On parle de variable de
classe.
• Ces variables sont, de plus, stockées une seule
fois, pour toutes les instances d'une classe.
• Mot réservé : static
• Accès :
• depuis une méthode de la classe comme pour tout
autre attribut,
• via une instance de la classe,
• à l'aide du nom de la classe.
118
Variables de classe (2)
Variable de classe
public class UneClasse
{
public static int compteur = 0;
public UneClasse ()
{
compteur++;
}
}
public class AutreClasse
{
public void uneMethode()
{
int i = UneClasse.compteur;
}
}
Utilisation de la variable de classe
compteur dans le constructeur de
la classe
Utilisation de la variable de classe
compteur dans une autre classe
119
Méthodes de classe (1)
• Il peut être nécessaire de disposer d'une méthode qui
puisse être appelée sans instance de la classe. C'est
une méthode de classe.
• On utilise là aussi le mot réservé static
• Puisqu'une méthode de classe peut être appelée sans
même qu'il n'existe d'instance, une méthode de
classe ne peut pas accéder à des attributs non
statiques. Elle ne peut accéder qu'à ses propres
variables et à des variables de classe.
120
Méthodes de classe (2)
public class UneClasse
{
public int unAttribut;
public static void main(String args[])
{
unAttribut = 5; // Erreur de compilation
}
}
La méthode main est une
méthode de classe donc elle
ne peut accéder à un attribut
non lui-même attribut de
classe
Autres exemples de méthodes de classe courantes
Math.sin(x);
String String.valueOf (i);
121
Modificateur de classe
122
• Précède la déclaration de la classe
•
•
•
•
•
Annotations (plus tard…)
public (par défaut package)
abstract(incomplète, pas d’instance)
final(pas d’extension)
Strictfp (technique…)
classes et objets
III) Champs
123
• Modificateurs
• annotations
• Contrôle d’accès
•
•
•
•
•
•
•
•
private
protected
public
package
static (variables de classe)
final (constantes)
transient
Volatile
• Initialisations
• Création par opérateur new
classes et objets
V) Méthodes
124
• Modificateurs:
•
•
•
•
•
•
•
•
Annotations
Contrôle d’accès (comme pour les variables)
abstract
static n’a pas accès aux variables
d’instances
final ne peut pas être remplacée
synchronized
native (utilisation de fonctions « native »)
strictfp
classes et objets
Composition d’objets (1)
• Un objet peut être composé à partir d’autres objets
Exemple : Une voiture composée de
• 5 roues (roue de secours) chacune composée
• d’un pneu
• d’un moteur composé
• de plusieurs cylindres
• de portières
• etc…
Chaque composant est un attribut de l’objet composé
125
Composition d’objets (2)
Syntaxe de composition d’objets
class Pneu {
private float pression ;
void gonfler();
void degonfler();}
class
Roue {
private float diametre;
Pneu pneu ;}
class Voiture {
Roue roueAVG,roueAVD, roueARG, roueARD , roueSecours ;
Portiere portiereG, portiereD;
Moteur moteur;}
126
Composition d’objets (3)
• Généralement, le constructeur d’un objet composé doit
appeler le constructeur de ses composants
public Roue () {
pneu = new Pneu();}
public Voiture () {
roueAVG = new Roue();
roueAVD = new Roue();
roueARG = new Roue();
roueARD = new Roue();
portiereG = new Portiere();
portiereD = new Portiere();
moteur = new Moteur();}
127
Composition d’objets (4)
• L’instanciation d’un objet composé instancie
ainsi tous les objets qui le composent
128
Chapitre IV
Héritage
L’héritage (1) : Concept
• La modélisation du monde réel nécessite une
classification des objets qui le composent
• Classification = distribution systématique en
catégories
selon des critères précis
• Classification = hiérarchie de classes
• Exemples :
• classification des éléments chimiques
• classification des êtres vivants
130
L’héritage (2) : exemple
131
L’héritage (3) : définition
• Héritage : mécanisme permettant le partage et la
réutilisation de propriétés entre les objets. La relation
d’héritage est une relation de généralisation /
spécialisation.
• La classe parente est la superclasse.
• La classe qui hérite est la sous-classe.
132
L’héritage (3) : représentation
graphique
Superclasse
Lien d’héritage
Sous-classe
Représentation avec UML d’un héritage (simple)
133
L’héritage avec Java (1)
• Java implémente le mécanisme d'héritage simple qui
permet de "factoriser" de l'information grâce à une
relation de généralisation / spécialisation entre deux
classes.
• Pour le programmeur, il s'agit d'indiquer, dans la sousclasse, le nom de la superclasse dont elle hérite.
• Par défaut toutes classes Java hérite de la classe Object
• L'héritage multiple n'existe pas en Java.
• Mot réservé :
extends
134
L’héritage avec Java (2)
class Personne
{
private String nom;
private Date date_naissance;
// ...
}
class Employe extends Personne
{
private float salaire;
// ...
}
class Etudiant extends Personne
{
private int numero_carte_etudiant;
// ...
}
135
L’héritage en Java (3)
• Constructeurs et héritage
• par défaut le constructeur d’une sous-classe appelle le
constructeur "par défaut" (celui qui ne reçoit pas de paramètres)
de la superclasse. Attention donc dans ce cas que le constructeur
sans paramètre existe toujours dans la superclasse...
• Pour forcer l'appel d'un constructeur précis, on utilisera le mot
réservé super. Cet appel devra être la première instruction du
constructeur.
136
L’héritage en Java (4)
public class Employe extends Personne
{
public Employe () {}
public Employe (String nom,
String prenom,
int anNaissance)
{
super(nom, prenom, anNaissance);
}
}
Appel explicite à ce constructeur
avec le mot clé super
public class Personne
{
public String nom, prenom;
public int anNaissance;
public Personne()
{
nom=""; prenom="";
}
public Personne(String nom,
String prenom,
int anNaissance)
{
this.nom=nom;
this.prenom=prenom;
this.anNaissance=anNaissance;
}
}
137
L’héritage en Java (5)
public class Personne
{
public String nom, prenom;
public int anNaissance;
public Personne()
{
nom=""; prenom="";
}
public Personne(String nom,
String prenom,
int anNaissance)
{
this.nom=nom;
this.prenom=prenom;
this.anNaissance=anNaissance;
}
}
public class Object
{
public Object()
{
… / ...
}
}
Appel par défaut dans le constructeur
de Personne au constructeur
par défaut de la superclasse de
Personne, qui est Object
138
Redéfinition de méthodes
• Une sous-classe peut redéfinir des méthodes existant
dans une de ses superclasses (directe ou indirectes),
à des fins de spécialisation.
• Le terme anglophone est "overriding". On parle aussi de
masquage.
• La méthode redéfinie doit avoir la même signature.
class Employe extends Personne
class Cadre extends Employe
{
{
redéfinition
private float salaire;
public calculePrime()
public calculePrime( )
{
{
// ...
// ...
}
}
// ...
}
}
139
Recherche dynamique des
méthodes (1)
• Le polymorphisme
• Capacité pour une entité de prendre plusieurs formes.
• En Java, toute variable désignant un objet est potentiellement
polymorphe, à cause de l'héritage.
• Polymorphisme dit « d’héritage »
• le mécanisme de "lookup" dynamique :
• déclenchement de la méthode la plus spécifique d’un objet,
c'est-à-dire celle correspondant au type réel de l'objet,
déterminé à l'exécution uniquement (et non le type de la
référence, seul type connu à la compilation, qui peut être plus
générique).
• Cette dynamicité permet d'écrire du code plus générique.
140
Recherche dynamique des
méthodes (2)
Employe jean = new Employe();
jean.calculePrime();
Employe
salaire : Double
calculePrime()
Cadre
Employe jean = new Cadre();
jean.calculePrime();
calculePrime()
141
Opérateur instanceof
• L'opérateur instanceof confère aux instances une
capacité d'introspection : il permet de savoir si une
instance est instance d'une classe donnée.
• Renvoie une valeur booléenne
if ( ... )
Personne jean = new Etudiant();
else
Personne jean = new Employe();
//...
if (jean instanceof Employe)
// discuter affaires
else
// proposer un stage
142
Forçage de type / transtypage
(1)
• Lorsqu'une référence du type d'une classe désigne
une instance d'une sous-classe, il est nécessaire de
forcer le type de la référence pour accéder aux
attributs spécifiques à la sous-classe.
• Si ce n'est pas fait, le compilateur ne peut
déterminer le type réel de l'instance, ce qui
provoque une erreur de compilation.
• On utilise également le terme de transtypage
• Similaire au « cast » en C
143
Forçage de type / transtypage
(2)
class Personne
{
private String nom;
private Date date_naissance;
// ...
}
class Employe extends Personne
{
public float salaire;
// ...
}
Personne jean = new Employe ();
float i = jean.salaire; // Erreur de compilation
float j = ( (Employe) jean ).salaire; // OK
A ce niveau pour le
compilateur dans la
variable « jean » c’est
un objet de la classe
Personne, donc qui
n’a pas d’attribut
« salaire »
On « force » le type
de la variable « jean »
pour pouvoir accéder
à l’attribut « salaire ».
On peut le faire car c’est
bien un objet Employe
qui est dans cette
variable 144
L’autoréférence : this (1)
• Le mot réservé this, utilisé dans une méthode,
désigne la référence de l'instance à laquelle le
message a été envoyée (donc celle sur laquelle la
méthode est « exécutée »).
• Il est utilisé principalement :
• lorsqu'une référence à l'instance courante doit être passée
en paramètre à une méthode,
• pour lever une ambiguïté,
• dans un constructeur, pour appeler un autre constructeur de
la même classe.
145
L’autoréférence : this (2)
class Personne
{
public String nom;
Personne (String nom)
{
this.nom=nom;
}
}
Pour lever l’ambiguïté sur le mot « nom »
et déterminer si c’est le nom du paramètre
ou de l’attribut
public MaClasse(int a, int b) {...}
public MaClasse (int c)
{
this(c,0);
}
public MaClasse ()
{
this(10);
}
Appelle le constructeur
MaClasse(int a, int b)
Appelle le constructeur
MaClasse(int c)
146
Classes abstraites (1)
• Il peut être nécessaire au programmeur de créer une
classe déclarant une méthode sans la définir (c'est-àdire sans en donner le code). La définition du code
est dans ce cas laissée aux sous-classes.
• Une telle classe est appelée classe abstraite.
• Elle doit être marquée avec le mot réservé abstract.
• Toutes les méthodes de cette classe qui ne sont pas
définies doivent elles aussi être marquées par le mot
réservé abstract.
• Une classe abstraite ne peut pas être instanciée.
147
Classes abstraites (2)
• Par contre, il est possible de déclarer et d'utiliser des
variables du type de la classe abstraite.
• Si une sous-classe d'une classe abstraite ne définit
pas toutes les méthodes abstraites de ses
superclasses, elle est abstraite elle aussi.
public abstract class Polygone
{
private int nombreCotes = 3;
public abstract void dessine (); // methode non définie
public int getNombreCotes()
{
return(nombreCotes);
}
}
148
Notion d’ « Interfaces »
• Pour définir qu'une certaine catégorie de classes doit
implémenter un ensemble de méthodes, on peut regrouper
les déclarations de ces méthodes dans une interface.
• Le but est de décrire le fait que de telles classes pourront
ainsi être manipulées de manière identique.
• Exemple :
• Tous les appareils électriques peuvent être allumés ou éteint
• Tous les objets comestibles peuvent être mangés
• Tous les objets lumineux éclairent
149
Définition d’Interface
• Une interface est donc la description d’un ensemble des
procédures (méthodes) que les classes Java peuvent
mettre en œuvre.
• Les classes désirant appartenir à la catégorie ainsi
définie
• déclareront qu'elles implémentent cette interface,
• fourniront le code spécifique des méthodes déclarées dans cette
interface.
• Cela peut être vu comme un contrat entre la classe et
l’interface
• la classe s’engage à implémenter les méthodes définies dans
l’interface
150
Codage d’une interface en Java
• Mot réservé : interface
• Dans un fichier nom_interface.java, on définit la
liste de toutes les méthodes de l’interface
interface nomInterface {
type_retour methode1(paramètres);
type_retour methode2(paramètres);
… }
• Les méthodes d'une interface sont abstraites : elles
seront écrites spécifiquement dans chaque classe
implémentant l’interface
• Le modificateur abstract est facultatif.
151
Implémentation d’une interface
dans une classe
• Mot réservé : implements
• La classe doit expliciter le code de chaque méthode
définie dans l’interface
class MaClasse implements nomInterface {
…
type_retour methode1(paramètres)
{code spécifique à la méthode1 pour cette classe};
… }
152
Exemple d’Interface (1)
interface Electrique
{
void allumer();
void eteindre();
}
class Radio implements Electrique
{
// ...
void allumer() {System.out.println(« bruit »);}
void eteindre() {System.out.println(« silence »);}
class Ampoule implements Electrique
{
// ...
void allumer() {System.out.println(« j’éclaire »);}
void eteindre() {System.out.println(« plus de lumière»);}
}
153
Exemple d’Interface (2)
// …
Ampoule monAmpoule = new Ampoule();
Radio maRadio = new Radio();
Electrique c;
Boolean sombre;
// …
if(sombre == true)
c = monAmpoule;
else
c = maRadio;
c.allumer();
…
c.eteindre();
// …
154
Utilisation des interfaces
Une
variable peut être définie selon le type d’une interface
Une classe peut implémenter plusieurs interfaces différentes
L’opérateur instanceof peut être utilisé sur les interfaces
Exemple :
interface Electrique
…
interface Lumineux
…
class Ampoule implements Electrique, Lumineux
…
Electrique e;
Object o = new Ampoule();
155
if (o instanceof Electrique) {e=(Electrique)o;e.allumer();}
Conclusion sur les interfaces
• Un moyen d’écrire du code générique
• Une solution au problème de l’héritage multiple
• Un outil pour concevoir des applications réutilisables
156
Chapitre V – La généricité
157
Principes généraux de la généricité
Généricité
Principes
158
• Paramétrer une classe ou une méthode par un type:
• une pile de X
• En java toute classe étant dérivée de Object, cela
permet d'obtenir une forme de généricité sans
contrôle des types
• une pile d'Object
• La généricité en Java est un mécanisme "statique"
assez complexe
• la généricité existe dans d'autres langages (exemple
C++ et Ada) (mais de façon différente)
Généricité
Exemple: Classe non générique
159
class TestGenerique{
int valeur;
TestGenerique(){
valeur=0;
}
TestGenerique(int v){
valeur=v;
}
public void setValeur(int v){
valeur=v;
}
public String getValeur(){
return valeur;
}
}
TestGenerique tg=new TestGenerique(10);
tg.setValeur(20);
System.out.println(tg.getValeur());
OK fonctionne
TestGenerique tg=new TestGenerique("Bonjour");
tg.setValeur("Le monde");
System.out.println(tg.getValeur());
Ne fonctionne pas
Généricité
L’opérateur diamant <>
160
Pour rendre notre classe générique, on vas utiliser l’opérateur « Diamant » noté
<>, cet opérateur permet mis devant une classe de passer à cette même classe
un type génrérique à la classe.
L’opérateur diamant <UNNOM> prend entre les chevrons un nom qui sera le nom
générique du type.
Exemple : class maClasse<UnTypeGenerique>{ …. }
Généricité
Rendre générique une classe
161
class TestGenerique{
int valeur;
TestGenerique(){
valeur=0;
}
TestGenerique(int v){
valeur=v;
}
Il faut pour cela rendre
générique les types que l’on
rencontre dans notre classe.
Ici int dans notre exemple.
public void setValeur(int v){
valeur=v;
}
public int getValeur(){
return valeur;
}
}
Généricité
Utilisation de l’opérateur <>
162
class TestGenerique<T>{
T valeur;
TestGenerique(){
valeur=0;
}
TestGenerique(T v){
valeur=v;
}
On va placer notre opérateur
<T> après le nom de la classe
On remplace l’ensemble des
types par notre type générique T
public void setValeur(T v){
valeur=v;
}
public T getValeur(){
return valeur;
}
}
Généricité
Utilisation de l’opérateur <>
class TestGenerique<T>{
163
T valeur;
TestGenerique(){
valeur=0;
}
TestGenerique(T v){
valeur=v;
}
public void setValeur(T v){
valeur=v;
}
public T getValeur(){
return valeur;
}
}
TestGenerique<int> tg=new TestGenerique(10);
tg.setValeur(20);
System.out.println(tg.getValeur());
On indique lors de la création de
l’instance de l’objet, le type
générique de la classe
TestGenerique<String> tg=new TestGenerique("Bonjour");
tg.setValeur("Le monde");
System.out.println(tg.getValeur());
Maintenant notre classe est devenu générique,
elle fonctionne quelquesoit le type simple
utilisé ou avec un nom de classe comme type.
Remarques
164
• Une déclaration de type générique peut avoir
plusieurs paramètres:
• Map<K,V>
Généricité
Chapitre VI
Exceptions
VI) Exceptions
1.
2.
3.
4.
5.
Principes généraux
Déclarations de throws
try, catch et finally
Transfert d'information: chainage, pile
Assertions
166
Exceptions et assertions
• principe:
• traitement des "erreurs"
• quand une exception est lancée:
• rupture de l'exécution séquentielle
• "dépiler" les méthodes et les blocs
• jusqu'à un traite exception adapté
• erreur:
• rupture du contrat:
• précondition violée
167
Exceptions
• checked ou unchecked
• checked: cas exceptionnel, mais dont
l'occurrence est prévue et peut être traitée
(exemple: valeur en dehors des conditions de la
précondition, …)
• Une méthode qui peut lancer une checked
exception doit le déclarer
• unchecked: il n'y a rien à faire, (exemple une
erreur interne de la JVM) ou une erreur à
l'exécution (dépassement de tableau)
• Une méthode qui peut lancer une unchecked
exception ne doit pas le déclarer
168
Exceptions
• Une exception est un objet d'une classe dérivée de
Throwable.
• Le mécanisme est le même que pour tout objets:
•
•
•
•
on peut définir des sous-classes
des constructeurs
redéfinir des méthodes
ajouter des méthodes
169
Exceptions et traite-exceptions
• Un traite exception déclare dans son entête un
paramètre
• Le type du paramètre détermine si le traiteexception correspond à l'exception
• même mécanisme que pour les méthodes et
l'héritage
170
Throw
• Certaines exceptions et errors sont lancées par
la JVM
• L'utilisateur peut définir ses propres
exceptions et les lancer lui-même:
throw expression;
l'expression doit s'évaluer comme
une valeur ou une variable qui
peut être affectée à Throwable
171
Environnement
• Par définition une exception va transférer
le contrôle vers un autre contexte
• le contexte dans lequel l'exception est traitée
est différent du contexte dans lequel elle est
lancée
• l'exception elle-même peut permettre de
passer de l'information par son instanciation
• l'état de la pile au moment de l'exception est
aussi transmis
public StackTraceElement[] getStackTrace() et
public void printStackTrace()
172
Hiérarchie:
• java.lang.Throwable (implements java.io.Serializable)
• java.lang.Error
•
•
•
•
java.lang.AssertionError
java.lang.LinkageError
java.lang.ThreadDeath
java.lang.VirtualMachineError
• exemple:java.lang.StackOverflowError
• java.lang.Exception
•
•
•
•
•
•
•
•
java.lang.ClassNotFoundException
java.lang.CloneNotSupportedException
java.lang.IllegalAccessException
java.lang.InstantiationException
java.lang.InterruptedException
java.lang.NoSuchFieldException
java.lang.NoSuchMethodException
java.lang.RuntimeException
• exemple: java.lang.IndexOutOfBoundsException
173
Hiérarchie
• Throwable:
• la super classe des erreurs et des exceptions
• Error : unchecked
• Exception :checked sauf RuntimeException
174
Exemple
public class MonException extends
Exception{
public final String nom;
public MonException(String st) {
super("le nombre "+st+" ne figure
pas");
nom=st;
}
}
175
Exemple (suite)
class Essai{
static String[] tab={"zéro","un","deux","trois","quatre"};
static int chercher(String st ) throws MonException{
for(int i=0;i<tab.length;i++)
if (tab[i].equals(st))return i;
throw new MonException(st);
}
public static void main(String st[]){
try{
chercher("zwei");
}catch(Exception e){
System.out.println(e);
}
}
}
176
Résultat
• Donnera:
exceptions.MonException: le nombre zwei ne figure
pas
• e.printStackTrace(); dans le try bloc
donnera:
exceptions.MonException: le nombre zwei ne figure
pas
at
exceptions.Essai.chercher(MonException.java:29)
at
exceptions.Essai.main(MonException.java:34)
177
Throws
• principe:
• toute méthode qui peut générer directement ou
indirectement une (checked) exception doit le
déclarer par une clause "throws" dans l'entête de la
méthode.
• (les initialiseurs statiques ne peuvent donc pas
générer d'exceptions)
• La vérification a lieu à la compilation
178
Clause throws
• Une méthode qui appelle une méthode qui
peut lancer une exception peut
• attraper (catch) cette exception dans un try bloc
englobant la méthode qui peut lancer cette
exception
• attraper cette exception et la transformer en une
exception déclarée dans la clause throws de la
méthode
• déclarer cette exception dans la clause throws de sa
déclaration
179
Clause throws et héritage
• Si une classe dérivée redéfinit (ou
implémente) une méthode la clause throws de
la méthode redéfinie doit être compatible
avec celle d'origine
• compatible = les exceptions de la clause throws sont
dérivées de celles de la méthode d'origine
• pourquoi?
180
try, catch, finally
• On attrape les exceptions dans des try-bloc:
try{
instructions
}catch(exception-type1 id1){
instructions
} catch(exception-type2 id2){
...
}finally{
instructions
}
181
Principe:
• le corps du try est exécuté jusqu'à ce qu'il
termine ou qu'une exception est lancée
• Si une exception est lancée les clauses
"catch" sont examinées dans l'ordre
• la première dont le type peut correspondre à
l'exception est choisie et son code exécuté
• si aucun catch ne peut correspondre l'exception
est propagée
• si une clause finally figure son code est ensuite
exécuté (toujours avec ou sans exception)
182
Exemple
class A extends Exception{
}
class B extends A{
}
class essai{
public static void main(String[] st){
try{
throw new B();
}catch (A a){
System.out.println(a);
//
}catch (B b){
//
System.out.println(b);
}finally{
System.out.println("finally..");
}
}
}
183
finally
public boolean rechercher(String fichier,
String mot) throws StreamException{
Stream input=null;
try{
input=new Stream(fichier);
while(!input.eof())
if(input.next().equals(mot))
return true;
return false;
}finally{
if (input != null)
input.close();
}
}
184
Chaînage d'exceptions
• Une exception peut être causée par une autre.
• il peut être utile dans ce cas de transmettre la
cause de l'exception
• méthode:
public Throwable initCause(Throwable cause)
185
Transmission d'information
• en définissant une extension de la classe et en
définissant des constructeurs
• par défaut on a les constructeurs
public Throwable()
public Throwable(String message)
public Throwable(String message, Throwable cause)
186
Transmission d'information
• On peut récupérer ces informations:
public String getMessage()
public Throwable getCause()
• On peut obtenir l'état de la pile:
public void printStackTrace()
public StackTraceElement[]
getStackTrace()
187
Exemple
class X extends Exception{
public X(){}
public X(String details){
super(details);
}
public X(Throwable e){
super(e);
}
public X(String details, Throwable e){
super(details,e);
}
}
188
Suite
try{
throw new A();
}catch (A a){
try {
throw new X(a);
} catch (X ex) {
ex.printStackTrace();
}
}
}
-----
X: A
at essai.main(Finally.java:61)
Caused by: A
at essai.main(Finally.java:58)
189
Remarque
• à la place de:
throw new X(a);
• on pourrait mettre
throw (X) new X().initCause(a);
(pourquoi le cast (X) est nécessaire?)
190
Java Swing
Principes de base
• Des composants graphiques
(exemple: JFrame, JButton …)
• Hiérarchie de classes
• Des événements et les actions à effectuer
(exemple presser un bouton)
• (Et d'autres choses…)
Principes
• Définir les composants (instance de
classes)
• Les placer à la main (layout Manager) dans
un JPanel ou un content pane ou en
utilisant des outils comme eclipse ou
netbeans
• Définir les actions associées aux
événements (Listener) et les associer aux
composants graphiques
Principes
• Dans une interface graphique, le programme
réagit aux interactions avec l'utilisateur
• Les interactions génèrent des événements
• Le programme est dirigé par les événements
(event-driven)
Afficher…
• Pour pouvoir être affiché, il faut que le
composant soit dans un top-level conteneur:
(JFrame, JDialog et JApplet)
• Hiérarchie des composants: arbre racine toplevel
Exemple
• Correspond à la hiérarchie
Le code
import java.awt.*;
import javax.swing.*;
public class TopLevel {
/*** Affiche une fenêtre JFrame top level
* avec une barre de menu JMenuBar verte
* et un JLabel jaune */
private static void afficherMaFenetre() {
//créer la Jframe
//créer la JMenuBar
//créer le Jlabel
// mettre le JMenuBar et le Jlable dans la Jframe
//afficher la Jframe
}
}
Le code
//Creer la JFrame
JFrame frame = new JFrame("TopLevelDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Créer la JMenuBar
JMenuBar greenMenuBar = new JMenuBar();
greenMenuBar.setOpaque(true);
greenMenuBar.setBackground(new Color(0, 200, 0));
greenMenuBar.setPreferredSize(new Dimension(200, 20));
//Créer le JLabel
JLabel yellowLabel = new JLabel();
yellowLabel.setOpaque(true);
yellowLabel.setBackground(new Color(250, 250, 0));
yellowLabel.setPreferredSize(new Dimension(200, 180));
//mettre la JmenuBar et position le JLabel
frame.setJMenuBar(greenMenuBar);
frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
//afficher...
frame.pack();
frame.setVisible(true);
Et le main
public class TopLevel {//afficherMaFenetre()
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
afficherMaFenetre();
}
});
}
}
Evénements: principes
• Dans un système d'interface graphique:
• Quand l'utilisateur presse un bouton, un
"événement" est posté et va dans une boucle
d'événements
• Les événements dans la boucle d'événements sont
transmis aux applications qui se sont enregistrées
pour écouter.
Evénements
• Chaque composant génère des
événements:
• Presser un Jutton génère un ActionEvent
(système d'interface graphique)
• Cet ActionEvent contient des infos (quel bouton,
position de la souris, modificateurs…)
• Un event listener (implémente ActionListener)
• définit une méthode actionPerformed
• S'enregistre auprès du bouton addActionListener
• Quand le bouton est "clické",l'actionPerformed
sera exécuté (avec l'ActionEvent comme
paramètre)
Exemples Buttons
Un exemple
• Un bouton qui réagit
Le code:
• Un JButton
• Un JLabel
• Implementer ActionListener
• actionPerfomed définit ce qui se passe quand le
bouton est cliqué
• Placer le bouton et le label
Code:
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.Jcomponent;
import java.awt.Toolkit;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JLabel;
public class UnBouton extends Jpanel implements ActionListener {
JButton bouton;
String contenu="Rien Reçu";
JLabel label=new JLabel(contenu);
int cmp=0;
public UnBouton() { //…}
public void actionPerformed(ActionEvent e) {//…}
private static void maFenetre(){//…}
public static void main(String[] args) {//…}
}
Code
public UnBouton() {
super(new BorderLayout());
bouton = new JButton("Click");
bouton.setPreferredSize(new Dimension(200, 80));
add(bouton, BorderLayout.NORTH);
label = new JLabel(contenu);
label.setPreferredSize(new Dimension(200, 80));
add(label,BorderLayout.SOUTH);
bouton.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
label.setText("clické "+ (++cmp)+ " fois");
}
Code
private static void maFenetre() {
JFrame frame = new JFrame("UnBouton");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new UnBouton();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Formule magique
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
maFenetre();
}
});
}
Variante
public class UnBoutonBis extends JPanel {
//…
bouton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
label.setText("clické " + (++cmp) + " fois");
} });
}
//…
}
Hiérarchie des classes…
209
Un exemple
• Un traceur de fonctions
• Une interface graphique swing
Organisation
• GrapheSwing contient unGraphePanel
extension de Jpanel
• GraphePanel méthode paintComponent qui affiche
le graphe de la fonction
• Graphe est la classe contenant le gaphe et
définissant une méthode draw pour l'affichage
• Cette méthode appelle tracer de la classe abstraite
Traceur
• FonctionTraceur étend Traceur
212
Le main
public static void main(String[] args) { new GrapheSwing(unGraphe());}
public static Graphe unGraphe() {
PlotSettings p = new PlotSettings(-2, 2, -1, 1);
p.setPlotColor(Color.RED);
p.setGridSpacingX(0.5);
p.setGridSpacingY(0.5);
p.setTitle("Une parabole et une sinusoide");
Graphe graphe = new Graphe(p);
graphe.functions.add(new Parabole());
graphe.functions.add(new FonctionTraceur() {
public double getY(double x) {
return Math.sin(x);
}
public String getName() {
return "Sin(x)";
}
});
213
Composants
• Modèle Vue Contrôleur
Préliminaires…
• Lightweight et heavyweight composants
• Dépendent ou non du système d’interface
graphique
• Lightweight écrit en Java et dessinés dans un
heavyweight composant- indépendant de la
plateforme
• Les heavyweight composants s’adressent
directement à l’interface graphique du système
• (certaines caractéristiques dépendent du
look and feel).
Look and feel
• Look and feel:
Possibilité de choisir l’apparence de l’interface
graphique.
UIManager gère l’apparence de l’interface
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) { }
new SwingApplication(); //Create and show the GUI.
}
Multithreading
• Attention au « modèle, contrôleur, vue » en
cas de multithreading:
• Tous les événements de dessin de l’interface
graphiques sont dans une unique file d’eventdispatching dans une seule thread.
• La mise à jour du modèle doit se faire tout de suite
après l’événement de visualisation dans cette
thread.
Plus précisément
• Swing prend en charge la gestion des
composants qui sont dessinés en code Java
(lightweight)
• Les composants AWT sont eux liés aux
composants natifs (heavyweight)
• Swing dessine le composants dans un canevas
AWT et utilise le traitement des événements
de AWT
Suite
Les threads
• Main application thread
• Toolkit thread
• Event dispatcher thread
• Toutes Les opérations
d'affichage ont lieu dans
une seule thread l'EDT
Principes
• Une tâche longue ne doit pas être exécutée
dans l'EDT
• Un composant Swing doit s'exécuter dans l'EDT
Exemple
public void actionPerformed(ActionEvent e){
try {
Thread.sleep(4000);
} catch (InterruptedException e) { } }
Provoque une interruption de l'affichage pendant 4
secondes
Une solution
public void actionPerformed(ActionEvent e){
try{
SwingUtilities.invokeLater(newRunnable(
{ public void run() {
//opération longue
}
});
} catch (InterruptedException ie) {}
catch (InvocationTargetException ite) {}
}
}
Le main
• Normalement la création d'une fenêtre ne devrait
avoir lieu que dans l'EDT:
public static void main(String[] args) {
//Formule magique
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run() {maFenetre(); }
});
}
invokeLater crée une nouvelle thread qui poste la thread
crée dans l'EDT
Attendre le résultat:
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
show();
}
});
} catch (InterruptedException ie) {
} catch (InvocationTargetException ite) {
}
Chapitre VIII
Strings, en savoir plus
Plan
•
•
•
•
226
A) String
B) Expressions régulières
C) Chaînes et tableaux (char et byte)
D) Chaînes modifiables
Strings
String
227
• Une String est une chaîne de caractères
non modifiable
• (attention les caractères en java sont en
Unicode)
• StringBuilder et StringBuffer sont
des classes de chaînes qui peuvent être
modifiées.
• String StringBuilder et
StringBuffer implémentent l'interface
CharSequence
Strings
CharSequence
228
• Interface:
• char charAt(int index)
Retourne le char the char en position
index.
• int length()
Retourne la longueur de la séquence.
• CharSequence subSequence(int start, int end)
Retourne une sous CharSequence
• String toString()
Retourne la string correspondant à la
séquence
Strings
String
229
• De nombreuses méthodes pour manipuler
les chaines (attention un objet String n'est
pas modifiable)
• constructeurs
• indexOf, lastIndexOf retourne la première
(dernière) position
• conversion valueOf( valeur d'un type primitif)
• replace, trim, split
• toLowerCase, toupperCase()
• …
Strings
Comparaison
230
• '==' ne compare les contenus, MAIS deux
littéraux ayant le même contenu sont
identiques:
String st1="bonjour";
String st2="bonjour"
if(st1==st2)System.out.println("égal");
else System.out.println("différent");
donnera égal
La méthode intern permet de retourner un String de
même référence
Strings
Manipulations sur les chaînes
•
•
•
•
•
•
•
•
•
•
•
231
char charAt(int index)
int compareTo(String anotherString) comparaison lexicographique
boolean contains(CharSequence s)
boolean equals(Object anObject)
int length()
boolean matches(String regex)
boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len)
boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len)
String replace(CharSequence target, CharSequence replacement)
String[] split(String regex)
String trim()
Strings
Exemples
232
String string = "Madam, I am Adam";
boolean
// true
b = string.startsWith("Mad");
b = string.endsWith("dam");
// true
b = string.indexOf("I am") > 0;
// true
b = string.matches("(?i)mad.*");
b = string.matches("(?i).*adam");
b = string.matches("(?i).*i am.*");
Strings
Exemple: remplacement
233
static String replace(String str, String pattern,
String replace) {
int s = 0;
int e = 0;
StringBuffer result = new StringBuffer();
while ((e = str.indexOf(pattern, s)) >= 0) {
result.append(str.substring(s, e));
result.append(replace);
s = e+pattern.length();
}
result.append(str.substring(s));
return result.toString();
}
Strings
Exemple
234
Strinf st1="bonjour";
String st3=new String("bonjour");
if(st1==st3)System.out.println("égal");
else System.out.println("différent");
String st4=st3.intern();
if(st1==st4)System.out.println("égal");
else System.out.println("différent");
(la comparaison des références est bien sûr moins
coûteuse que la comparaison des contenus)
(de plus dans tous les cas des chaînes de même
contenus ont le même hashcode)
Strings
Expressions régulières
235
• Les expressions régulières permettent de
définir un motif (pattern) objet de la classe
Pattern.
• Un motif est créé par la méthode compile
• Pattern pat = Pattern.compile("[a-z]*")
Strings
Expressions régulières
236
• la syntaxe des expressions régulières (rationnelles) est assez large:
• caractères
• exemples \t , a ,\xhh ,
• classes de caractères
• exemples [a-z], [^a-z], [a-z&&0-9]
• classes de caractères prédéfinis
• exemples . , \d, \D, \w, \W, \s, \S
• classes prédéfinies ASCII, Character
• exemples \p{Blank}, \p{javaLowerCase}
• bords
• exemples ^, $,\b (bord d'un mot)
• itérations
• exemples [a-z]?, [1-9][0-9]+, \W*,
• capture et restitution
• (X) définit la capture de X
• \n correspond à la n-ième capture
Strings
Recherche de motif
237
• Principe:
Pattern pat=Pattern.compile(regex);
Matcher matcher=pat.match(entrée);
boolean trouve = matcher.find();
la classe Matcher contient les méthodes pour chercher
(find()), retourner la sous-séquence trouvée
(group())
Strings
Exemple: rechercher
238
String patternStr = "b";
Pattern pattern =
Pattern.compile(patternStr);
CharSequence inputStr = "a b c b";
Matcher matcher = pattern.matcher(inputStr);
boolean matchFound = matcher.find();
//
true
String match = matcher.group();
// b
int start = matcher.start();
// 2
int end = matcher.end();
// 3
matchFound = matcher.find();
//
true
Strings
Remplacer
CharSequence inputStr = "ab12 cd efg34";
String patternStr = "([a-zA-Z]+[0-9]+)";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(inputStr);
// Remplacer toutes les occurrences
StringBuffer buf = new StringBuffer();
boolean found = false;
while ((found = matcher.find())) {
String replaceStr = matcher.group();
replaceStr = replaceStr.toUpperCase();
matcher.appendReplacement(buf, replaceStr);
}
matcher.appendTail(buf);
Strings
String result = buf.toString();
// AB12 cd EFG34
239
Chaines et tableaux de char
240
• Une string n'est pas un tableau de char mais on
peut passer de l'un à l'autre
• constructeurs
String(char[] value)
String(char[] value, int offset, int count)
• méthode:
void getChars(int srcBegin, int srcEnd, char[] dst,
int dstBegin)
Strings
Chaînes et tableaux de byte
241
• les chaines contiennent des caractères codés
en UTF-16.
• On peut convertir ces caractères en byte
suivant un codage
• De même on peut coder des bytes en
caractères unicode.
• (par exemple un byte Latin-1 se code en
Unicode en ajoutant un octet de 0)
Strings
Charset
242
• la classe Charset permet de faire correspondre
des séquences d'unicode et des bytes. En
standard:
•
•
•
•
•
•
US-ASCII
ISO-8859-1
UTF-8
UTF-16BE
UTF-16LE
UTF-16
Strings
tableau de byte
243
• constructeurs:
• String(byte[] bytes) (conversion suivant le jeu de caractère
par défaut)
• String(byte[] bytes, int offset, int length)
• String(byte[] bytes, String charsetName) (suivant le
charset)
• String(byte[] bytes, int offset, int length,
String charsetName) (suivant le charset)
• méthodes
•
•
byte[]getBytes()
byte[]getBytes(String charsetName)
Strings
Exemple:
244
try {
// Conversion Unicode en x-MacRoman
String string = "abcéçùà\u563b";
System.out.println(string);
byte[] mac = string.getBytes("x-MacRoman");
System.out.println(new String(mac));
// Conversion x-MacRoman vers Unicode
string = new String(utf8, "x-MacRoman");
System.out.println(string);
} catch (UnsupportedEncodingException e) {
}
• abcéçùà?
• abcŽ??ˆ?
• abcéçùà?
Strings
Exemples:
245
for(String nom: Charset.availableCharsets().keySet())
System.out.println(nom);
affichera la liste des jeux de caractères:
•
EUC-JP
•
EUC-KR
•
GB18030
•
GB2312
•
GBK
•
IBM-Thai
•
IBM00858
•
IBM01140
•
IBM01141
•
IBM01142
•
IBM01143
•
IBM01144
•
IBM01145
•
IBM01146
•
IBM01147
•
IBM01148
•
…
Strings
Exemple
246
Charset charset = Charset.forName("ISO-8859-1");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();
try {
// Convertit une string vers ISO-LATIN-1
ByteBuffer bbuf =
encoder.encode(CharBuffer.wrap("une
chaîne"));
// Convertit ISO-LATIN-1 bytes en string.
CharBuffer cbuf = decoder.decode(bbuf);
String s = cbuf.toString();
} catch (CharacterCodingException e) {
}
Strings
Exemple:
247
try {
// Conversion vers ISO-LATIN-1 de bytes
ByteBuffer bbuf =
encoder.encode(CharBuffer.wrap("une chaîne"));
// Conversion de ISO-LATIN-1 vers bytes
CharBuffer cbuf = decoder.decode(bbuf);
String s = cbuf.toString();
System.out.println(s);
} catch (CharacterCodingException e) {
}
Strings
StringBuilder
248
• La classe StringBuilder peut contenir des
chaînes qui peuvent être modifiées.
• Il s'agit d'une structure de données dynamique: la
taille de la chaîne est augmentée automatiquement
• La taille initiale peut être précisée dans le
constructeur (16 par défaut).
• (Il existe aussi une classe StringBuffer qui est
"thread-safe")
• méthodes insert, append, delete
Strings
Chapitre IX
Entrées-sorties
Principes généraux
250
• entrées sorties
• streams dans java.io
• channels dans java.nio ("n" pour non-blocking)
• streams: séquences de données ordonnées avec
une source (stream d'entrée) ou une destination
(stream de sortie)
• channels et buffer. Buffer contient les données
et le channel correspond à des connections
I/O package
Streams
251
• Deux grandes sortes de Stream
• character Streams contiennent des caractères UTF16
• byte Streams contiennent des octets
• Character versus byte
• InputStream ou OutputStream pour les byte
• Reader, Writer pour les character
• deux hiérarchies qui se correspondent
I/O package
Hiérarchie
252
• java.io.InputStream (implements java.io.Closeable)
• java.io.ByteArrayInputStream
• java.io.FileInputStream
• java.io.FilterInputStream
•
•
•
•
java.io.BufferedInputStream
java.io.DataInputStream (implements java.io.DataInput)
java.io.LineNumberInputStream
java.io.PushbackInputStream
• java.io.ObjectInputStream (implements java.io.ObjectInput,
java.io.ObjectStreamConstants)
• java.io.PipedInputStream
• java.io.SequenceInputStream
• java.io.StringBufferInputStream
I/O package
Hiérarchie
253
• java.io.OutputStream (implements
java.io.Closeable, java.io.Flushable)
• java.io.ByteArrayOutputStream
• java.io.FileOutputStream
• java.io.FilterOutputStream
• java.io.BufferedOutputStream
• java.io.DataOutputStream (implements
java.io.DataOutput)
• java.io.PrintStream (implements java.lang.Appendable,
java.io.Closeable)
• java.io.ObjectOutputStream (implements
java.io.ObjectOutput, java.io.ObjectStreamConstants)
• java.io.PipedOutputStream
I/O package
Hiérarchie
254
• java.io.Reader (implements
java.io.Closeable, java.lang.Readable)
• java.io.BufferedReader
• java.io.LineNumberReader
• java.io.CharArrayReader
• java.io.FilterReader
• java.io.PushbackReader
• java.io.InputStreamReader
• java.io.FileReader
• java.io.PipedReader
• java.io.StringReader
I/O package
Hiérarchie
255
• java.io.Writer (implements
java.lang.Appendable, java.io.Closeable,
java.io.Flushable)
•
•
•
•
java.io.BufferedWriter
java.io.CharArrayWriter
java.io.FilterWriter
java.io.OutputStreamWriter
• java.io.FileWriter
• java.io.PipedWriter
• java.io.PrintWriter
• java.io.StringWriter
I/O package
Streams d'octets
256
• Class InputStream
(toutes ces méthodes peuvent lancer IOEXception)
• abstract int read() lit un octet
• int read (byte[] b) lit et écrit dans b, (le nombre
d'octets lus dépend de b et est retourné
• int read(byte[] b, int off, int len)
• long skip(long n)
• int available() n d'octets pouvant être lus
• void mark(int readlimit) et void reset() pose d'une
marque et retour à la marque
• voidclose()
I/O package
Stream d'octets
257
• OutputStream
(toutes ces méthodes peuvent lancer IOEXception)
•
•
•
•
•
abstract void write(int b) écrit un octet
void write(byte[] b)
void write(byte[] b, int off, int len)
voidclose()
voidflush()
I/O package
Exemples
258
public static int compteIS(String st){
try{
InputStream in;
int n=0;
in= new FileInputStream(st);
while (in.avalaible()!=0){
System.out.println(in.read());
}
} catch(IOException ioe) {ioe.printStackTrace();}
return n;
}
I/O package
Exemples
259
public static void trOS(String fichier){
int b;
OutputStream out=null;
try{
if(f==null) out=System.out;
else
out=new FileOutputStream(fichier);
while((b= System.in.read())!=-1) out.write(b);
out.flush();
out.close();
}catch(IOException ex){
ex.printStackTrace();
}
}
I/O package
Reader-Writer
260
• Reader et Writer sont les deux classes abstraites
pour les streams de caractères:
• le read de InputStream retourne un byte comme octet de
poids faible d'un int alors que le read de Reader retourne
un char à partir de 2 octets de poids faible d'un int
I/O package
Reader
261
• essentiellement les mêmes méthodes que pour
InputStream:
•
•
•
•
•
•
•
•
•
int read()
int read(char[] cbuf)
abstract int read(char[] cbuf, int off, int len)
int read(CharBuffer target)
boolean ready() si prêt à lire
voidreset()
voidmark(int readAheadLimit)
booleanmarkSupported()
longskip(long n)
I/O package
Writer
262
• similaire à OutputStream mais avec des caractères au lieu
d'octets.
•
•
•
•
•
•
•
•
•
•
•
void write(char[] cbuf)
abstract void write(char[] cbuf, int off, int len)
void write(int c)
void write(int c)
void write(String str)
void write(String str, int off, int len)
Writer append(char c)
Writer append(CharSequence csq)
Writer append(CharSequence csq, int start, int end)
abstract void close()
abstract void flush()
I/O package
Exemples
263
public static int compteR(String st){
try{
Reader in;
int n=0;
if (st==null)
in=new InputStreamReader(System.in);
else
in= new FileReader(st);
for(; in.read() != -1;n++);
Catch(IOException ioe){ioe.printStackTrace();}
return n;
}
I/O package
Exemples
264
public static void trWr(String fichier){
int b;
Writer out=null;
try {
if(f==null)
out= new OutputStreamWriter(System.out);
else
out=new FileWriter(fichier);
while((b= System.in.read())!=-1)
out.write(b);
out.flush();
out.close();
}catch(IOException e){System.out.println(e);}
}
I/O package
Remarques
265
• les streams standard System.in et System.out sont des
streams d'octets
• InputStreamReader permet de passer de InputStream à
Reader
• System.in et System.out sont des PrintStream
(obsolète à remplacer par la version caractère
PrintWriter)
I/O package
InputStreamReader et
OutputStreamWriter
266
• conversion entre caractères et octets, la conversion est
donnée par un charset
• Constructeurs:
•
•
•
•
•
•
•
InputStreamReader(InputStream in)
InputStreamReader(InputStream in, Charset cs)
InputStreamReader(InputStream in, String charsetName)
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, Charset cs)
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
OutputStreamWriter(OutputStream out, String charsetName)
I/O package
Autres classes
267
• FileInputStream
• FileOutputStream
• FileReader
• FileWriter
• Ces classes permettent d'associer une stream à
un fichier donné par son nom (String) par un
objet File ou un objet FileDescriptor (un mode
append peut être défini pour les ecritures)
I/O package
Quelques autres classes
268
• Les filtres
•
•
•
•
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
• Buffered
•
•
•
•
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
• Tubes
• PipedInputStream
• PipedOutputStream
• PipedReader
• PipedWriter
I/O package
Exemple d'un filtre
269
class conversionMaj extends FilterReader{
public conversionMaj(Reader in){
super(in);
}
public int read() throws IOException{
int c=super.read();
return(c==-1?c:Character.toUpperCase((char)c));
}
public int read(char[] buf, int offset, int count)throws
IOException{
int nread=super.read(buf,offset,count);
int last=offset+nread;
for(int i=offset; i<last;i++)
buf[i] = Character.toUpperCase(buf[i]);
return nread;
}
}
I/O package
Exemple suite:
270
StringReader source=new StringReader("ma
chaîne");
FilterReader filtre=new conversionMaj(source);
int c;
try{
while((c=filtre.read())!= -1)
System.out.print((char)c);
}catch(IOException e){
e.printStackTrace(System.err);
}
I/O package
Pipe (tube)
271
• Un tube associe une entrée et un sortie: on lit
à une extrémité et on écrit à l'autre.
I/O package
Exemple pipe
class PipeExemple extends Thread{
private Writer out;
private Reader in;
public PipeExemple(Writer out,Reader in){
this.out=out;
this.in=in;
}
public void run(){
int c;
try{
try{
while ((c=in.read())!=-1){
out.write(Character.toUpperCase((char)c));
}
}finally{out.close();}
}catch(IOException e){e.printStackTrace(System.err);}
I/O package
}
}
272
Suite
PipedWriter out1=new PipedWriter();
PipedReader in1=new PipedReader(out1);
PipedWriter out2=new PipedWriter();
PipedReader in2=new PipedReader(out2);
PipeExemple pipe=new PipeExemple(out1, in2);
pipe.start();
try{
for(char c='a';c<='z';c++) {
out2.write(c);
System.out.print((char)(in1.read()));
}
}finally {
out2.close();
I/O package
}
273
ByteArray, String…
274
• java.io.InputStream (implements java.io.Closeable)
• java.io.ByteArrayInputStream
• java.io.StringBufferInputStream
• java.io.OutputStream (implements java.io.Closeable, java.io.Flushable)
• java.io.ByteArrayOutputStream
• java.io.Reader (implements java.io.Closeable, java.lang.Readable)
• java.io.CharArrayReader
• java.io.StringReader
• java.io.Writer (implements java.lang.Appendable, java.io.Closeable,
java.io.Flushable)
• java.io.CharArrayWriter
• java.io.StringWriter
I/O package
Print Streams
275
• java.io.PrintStream (implements
java.lang.Appendable, java.io.Closeable)
• java.io.PrintWriter
• méthode println()
I/O package
Streams pour les données
276
• DataInput: interface pour lire des bytes d'une
stream binaire et les transformer en données
java de type primitif
• DataOutput: interface pour convertir des
valeurs de type primitif en stream binaire.
I/O package
Sérialisation
277
• sauvegarder des objets java en flot
d'octets:
• objet vers byte: sérialisation
• byte vers objet: désérialisation
• java.io.ObjectInputStream (implements
java.io.ObjectInput,
java.io.ObjectStreamConstants)
• java.io.ObjectInputStream (implements
java.io.ObjectInput,
java.io.ObjectStreamConstants)
I/O package
Sauver des objets
278
• la serialisation-désérialisation doit permettre
de sauvegarder et restituer des objets.
• sauver et restituer des objets n'est pas si
simple. Pourquoi?
• interface serializable
• (alternative XML)
I/O package
Manipuler des fichiers…
279
La classe File
Les fichiers et les répertoires sont encapsulés dans la classe File du package java.io. Il
n'existe pas de classe pour traiter les répertoires car ils sont considérés comme des
fichiers.
Une instance de la classe File est une représentation logique d'un fichier ou d'un
répertoire qui peut ne pas exister physiquement sur le disque.
Depuis la version 1.2 du J.D.K., de nombreuses fonctionnalités ont été ajoutées à cette
classe :
•la création de fichiers temporaires (createNewFile, createTempFile, deleteOnExit)
•la gestion des attributs "caché" et "lecture seule" (isHidden, isReadOnly)
•des méthodes qui renvoient des objets de type File au lieu de type String
(getParentFile, getAbsoluteFile, getCanonicalFile, listFiles)
•une méthode qui renvoie le fichier sous forme d'URL (toURL)
I/O package
Manipuler des fichiers…
280
- boolean canRead() indique si le fichier peut être lu
- boolean canWrite() indique si le fichier peut être modifié
- boolean createNewFile() création d'un nouveau fichier vide
- File createTempFile(String, String) création d'un nouveau fichier dans le répertoire par
défaut des fichiers temporaires. Les deux arguments sont le préfixe et le suffixe du
fichier.
- File createTempFile(String, String, File) création d'un nouveau fichier temporaire. Les
trois arguments sont le préfixe et le suffixe du fichier et le répertoire.
- boolean delete() détruire le fichier ou le répertoire. Le booléen indique le succès de
l'opération
- deleteOnExit() demande la suppression du fichier à l'arrêt de la JVM
- boolean exists() indique si le fichier existe physiquement
- String getAbsolutePath() renvoie le chemin absolu du fichier
Manipuler des fichiers…
281
- boolean isAbsolute() indique si le chemin est absolu
- boolean isDirectory() indique si le fichier est un répertoire
- boolean isFile() indique si l'objet représente un fichier
- long length() renvoie la longueur du fichier
- String[] list() renvoie la liste des fichiers et répertoire contenu dans le répertoire
- boolean mkdir() création du répertoire
- boolean mkdirs() création du répertoire avec création des répertoires
manquants dans l'arborescence du chemin
- boolean renameTo() renommer le fichier
Chapitre X
Threads, le multitâche
Threads
283
• threads: plusieurs activités qui coexistent
et partagent des données
• exemples:
• pendant un chargement long faire autre chose
• coopérer
• processus versus threads
• problème de l'accès aux ressources partagées
• verrous
• moniteur
• synchronisation
thread
Cycle de vie d’une Thread
284
Principes de base
285
• extension de la classe Thread
• méthode run est le code qui sera exécuté.
• la création d'un objet dont la superclasse est
Thread crée la thread (mais ne la démarre
pas)
• la méthode start démarre la thread (et
retourne immédiatement)
• la méthode join permet d'attendre la fin de
la thread
• les exécutions des threads sont asynchrones et
concurrentes
thread
Exemple
286
class ThreadAffiche extends Thread{
private String mot;
private int delay;
ThreadAffiche(String w,int duree){
mot=w;
delay=duree;
}
public void run(){
try{
while(true){
System.out.println(mot);
Thread.sleep(delay);
}
}catch(InterruptedException e){
}
}
}
thread
Suite
287
public static void main(String[] args) {
new ThreadAffiche("PING", 10).start();
new ThreadAffiche("PONG", 30).start();
new ThreadAffiche("Splash!",60).start();
}
thread
Alternative: Runnable
288
• Une autre solution:
• créer une classe qui implémente l'interface
Runnable (cette interface contient la méthode
run)
• créer une Thread à partir du constructeur Thread
avec un Runnable comme argument.
thread
Exemple
289
class RunnableAffiche implements Runnable{
private String mot;
private int delay;
public RunnableAffiche(String w,int duree){
mot=w;
delay=duree;
}
public void run(){
try{
for(;;){
System.out.println(mot);
Thread.sleep(delay);
}
}catch(InterruptedException e){
}
}
}
thread
Suite
290
public static void main(String[] args) {
Runnable ping=new RunnableAffiche("PING", 10);
Runnable pong=new RunnableAffiche("PONG", 50);
new Thread(ping).start();
new Thread(pong).start();
}
thread
Synchronisation
291
• les threads s'exécutent concurremment et
peuvent accéder concurremment à des objets:
• il faut contrôler l'accès:
• thread un lit une variable (R1) puis modifie cette
variable (W1)
• thread deux lit la même variable (R2) puis la modifie
(W2)
• R1-R2-W2-W1
• R1-W1-R2-W2 résultat différent!
thread
Exemple
292
class X{
int val;
}
class Concur extends Thread{
X x;
int i;
String nom;
public Concur(String st, X x){
nom=st;
this.x=x;
}
public void run(){
i=x.val;
System.out.println("thread:"+nom+" valeur x="+i);
try{
Thread.sleep(10);
}catch(Exception e){}
x.val=i+1;
System.out.println("thread:"+nom+" valeur x="+x.val);
}
}
thread
Suite
293
public static void main(String[] args) {
X x=new X();
Thread un=new Concur("un",x);
Thread deux=new Concur("deux",x);
un.start(); deux.start();
try{
un.join();
deux.join();
}catch (InterruptedException e){}
System.out.println("X="+x.val);
}
donnera (par exemple)
• thread:un valeur x=0
• thread:deux valeur x=0
• thread:un valeur x=1
• thread:deux valeur x=1
• X=1
thread
Deuxième exemple
294
class Y{
int val=0;
public int increment(){
int tmp=val;
tmp++;
try{
Thread.currentThread().sleep(100);
}catch(Exception e){}
val=tmp;
return(tmp);
}
int getVal(){return val;}
}
class Concur1 extends Thread{
Y y;
String nom;
public Concur1(String st, Y y){
nom=st;
this.y=y;
}
public void run(){
System.out.println("thread:"+nom+" valeur="+y.increment());
}
}
thread
Suite
295
public static void main(String[] args) {
Y y=new Y();
Thread un=new Concur1("un",y);
Thread deux=new Concur1("deux",y);
un.start(); deux.start();
try{
un.join();
deux.join();
}catch (InterruptedException e){}
System.out.println("Y="+y.getVal());
}
-----------
• thread:un valeur=1
• thread:deux valeur=1
• Y=1
thread
Verrous
296
• à chaque objet est associé un verrou
• synchronized(expr) {instructions}
• expr doit s'évaluer comme une référence à un objet
• verrou sur cet objet pour la durée de l'exécution de
instructions
• déclarer les méthodes comme synchronized: la
thread obtient le verrou et le relâche quand la
méthode se termine
thread
synchronised(x)
297
class Concur extends Thread{
X x;
int i;
String nom;
public Concur(String st, X x){
nom=st;
this.x=x;
}
public void run(){
synchronized(x){
i=x.val;
System.out.println("thread:"+nom+" valeur x="+i);
try{
Thread.sleep(10);
}catch(Exception e){}
x.val=i+1;
System.out.println("thread:"+nom+" valeur x="+x.val);
}
}
}
thread
Méthode synchronisée
298
class Y{
int val=0;
public synchronized int increment(){
int tmp=val;
tmp++;
try{
Thread.currentThread().sleep(100);
}catch(Exception e){}
val=tmp;
return(tmp);
}
int getVal(){return val;}
}
------------
• thread:un valeur=1
• thread:deux valeur=2
• Y=2
thread
Mais…
299
• la synchronisation par des verrous peut
entraîner un blocage:
• la thread un (XA) pose un verrou sur l'objet A
et (YB) demande un verrou sur l'objet B
• la thread deux (XB) pose un verrou sur l'objet B
et (YA) demande un verrou sur l'objet A
• si XA –XB : ni YA ni YB ne peuvent êter
satisfaites -> blocage
• (pour une méthode synchronisée, le verrou
concerne l'objet globalement et pas
seulement la méthode)
thread
Exemple
300
class Dead{
Dead partenaire;
String nom;
public Dead(String st){
nom=st;
}
public synchronized void f(){
try{
Thread.currentThread().sleep(100);
}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+
" de "+ nom+".f() invoque "+ partenaire.nom+".g()");
partenaire.g();
}
public synchronized void g(){
System.out.println(Thread.currentThread().getName()+
" de "+ nom+".g()");
}
public void setPartenaire(Dead d){
partenaire=d;
}
}
thread
Exemple (suite)
301
final Dead un=new Dead("un");
final Dead deux= new Dead("deux");
un.setPartenaire(deux);
deux.setPartenaire(un);
new Thread(new Runnable(){public void
run(){un.f();}
},"T1").start();
new Thread(new Runnable(){public void
run(){deux.f();}
},"T2").start();
------------
• T1 de un.f() invoque deux.g()
• T2 de deux.f() invoque un.g()
thread
Synchronisation…
302
• wait, notifyAll notify
• attendre une condition / notifier le changement de
condition:
synchronized void fairesurcondition(){
while(!condition)
wait();
faire ce qu'il faut qaund la condition est
vraie
}
----------------synchronized void changercondition(){
… changer quelque chose concernant la condition
notifyAll(); // ou notify()
}
thread
Exemple (file: rappel Cellule)
303
public class Cellule<E>{
private Cellule<E> suivant;
private E element;
public Cellule(E val) {
this.element=val;
}
public Cellule(E val, Cellule suivant){
this.element=val;
this.suivant=suivant;
}
public E getElement(){
return element;
}
public void setElement(E v){
element=v;
}
public Cellule<E> getSuivant(){
return suivant;
}
public void setSuivant(Cellule<E> s){
this.suivant=s;
}
thread
File synchronisées
304
class File<E>{
protected Cellule<E> tete, queue;
private int taille=0;
public synchronized void enfiler(E item){
Cellule<E> c=new Cellule<E>(item);
if (queue==null)
tete=c;
else{
queue.setSuivant(c);
}
c.setSuivant(null);
queue = c;
notifyAll();
}
thread
File (suite)
305
public synchronized E defiler() throws
InterruptedException{
while (tete == null)
wait();
Cellule<E> tmp=tete;
tete=tete.getSuivant();
if (tete == null) queue=null;
return tmp.getElement();
}
thread
306
CHAPITRE XI
Les Applets
Qu’est ce qu’une applet ?
307
Une Applet, est une application Java qui s ’éxécute dans une page Web, elle
exploite le plugin Java pour IE/Firefox/Chrome etc.
Une Applet permet de réaliser très facilement des applications graphiques,
en dessinant directement sur le Canvas de l’applet, ou d’utiliser des objets
comme les boutons, boite d’éditions, etc…
Comment créer une Applet ?
Object
|
+----- Component { paint(); resize();
…}
|
+----- Container
|
+----- Panel
|
+--- Applet
|
+--- JApplet
• Une applet est un objet
graphique.
• Mais c'est aussi un objet actif
créé et contrôlé par le navigateur
Web
308
Une Applet est une application qui hérite de la
classe Japplet
Pour définir une applet, il faut ajouter la close «
import javax.swing.JApplet; ».
Public class MonApplet extends JApplet
implements MouseListener {
Public void init(){…}
}
Cycle de vie d’une applet
309
Dans une applet, il existe ce que l’on appel le « le cycle de vie d’une applet », ce
cycle correspond à un certains
nombres de méthodes que l'on peut surcharger.Ce cycle de vis correspond à un
certains nombres d'états de notre applet.
• Les applets sont sous le contrôle du navigateur WWW (Firefox, IE, Hot Java, etc.)
• L'interface décide quand charger les applets d'une page HTML (=> état inactif)
• L'interface (re)démarre une applet quand sa fenêtre est visible sur l'écran (=> état
actif)
• L'interface arrête l'applet quand elle disparaît de l'écran (=> état inactif)
• L'interface efface l'applet quand elle n'en a plus besoin.
Cycle de vie d’une applet
310
Les méthodes de la classe Applet
• les méthodes d'interface graphique (héritées):
public void paint(Graphics g);
311
• les méthodes de contrôle d'exécution (héritées) :
public void init();
public void start();
public void stop();
public void destroy();
Ces méthodes correspondent aux différents états de notre applet, et sont appelées
lorsque nécessaire par notre JVM.
Au premier lancement de l’applet => public void init (){…..}
Au démarrage de l’applet => public void start(){….}
A l’arrêt de l’applet => public void stop(){….}
A la destruction de l’applet => public void destroy(){….}
A l’affichage de l’applet => public void paint(Graphics g){….}
La méthode repaint() permet de redessiner explicitement le « canvas » de l’applet, on
appel pas directement la méthode paint().
Dessiner sur une applet
312
On remarquera que la méthode « paint » à pour paramètre un objet de la classe «
Graphics », la classe « Graphics » apporte un ensemble de méthodes permettant de
dessiner directement sur le « canvas de l'applet ».
En général, on utilise des méthodes de la classe Graphics en les appelant dans la
méthode paint de l'applet.
• Dessiner et remplir : texte, lignes, rectangles, cercles, ellipses, polygones, arcs,
images.
• Modifier : couleur, fonte, zone de dessin (« clipping area »)
• Mode de dessin : XOR avec une couleur donnée
Consultez l’aide sur les classes Graphics
Exemples de méthodes :
et Graphics2D des API Java
• g.setColor(bg);
• g.draw3DRect(0, 0, d.width - 1, d.height - 1, true);
• g.drawRoundRect(x, y, rectWidth, rectHeight, 10, 10);
Gestion de la souris, l’Interface
MouseListener…
Gestion de la souris dans une applet
=> Implements MouseListener
Dans la méthode init pour une applet ou le constructeur sinon :
addMouseListener(this) ;
Re-déclarer les 5 méthodes abstraites (obligatoire) :
Public void mousePressed(MouseEvent e){….}
Public void mouseClicked(MouseEvent e){….}
Public void mouseReleased(MouseEvent e){….}
Public void mouseExited(MouseEvent e){….}
Public void mouseEntered(MouseEvent e){….}
313
Appeler une Applet dans
une page Web
314
Le tag APPLET
But: inclure dans un document HTML un espace pour l'exécution d'une petite
application.
<APPLET
[CODEBASE = localisation_programme]
CODE=nom_fichier_programme
WIDTH=largeur_fenêtre
HEIGHT=hauteur_fenêtre
autres>
<PARAM NAME=nom1 VALUE=valeur1>
<PARAM NAME=nom2 VALUE=valeur2>
...
</APPLET>
Le tag PARAM permet d'envoyer des paramètres (strings) à l'applet.
Passage de paramètres a une
Applet
315
Transmettre un argument à une applet :
On transmet un argument à une applet par l’intermédiaire du code HTML :
< PARAM NAME = * VALUE = * >
< PARAM NAME = font VALUE = * >
Les * symbolisent les valeurs que vous devez spécifier, la première le nom du
paramètre et la seconde sa valeur..
Récupérer un argument à partir d’une applet :
Pour récupérer à partir d’une applet les arguments transmis par le HTML, on utilise
la méthode getParameter().
TypeDeDonnée NomDeLaVariable = getParameter (" nomDuParamètre " ) ;
String theFont = getParameter(" font ") ;
Chapitre XII
Structures collectives en Java
Définition d ’une collection
317
Une collection regroupe plusieurs données de même
nature
 Exemples : promotion d’étudiants, sac de billes, ...
Une structure collective implante une collection
plusieurs implantations possibles
 ordonnées ou non, avec ou sans doublons, ...
 accès, recherche, tris (algorithmes) plus ou moins efficaces
Objectifs
adapter la structure collective aux besoins de la collection
ne pas re-programmer les traitements répétitifs classiques
(affichage, saisie, recherche d’éléments, …)
Structures collectives classiques
318
Tableau
type[]
et
Array
accès par index
recherche efficace si le tableau est trié (dichotomie)
insertions et suppressions peu efficaces
défaut majeur : nombre d’éléments borné
Liste
interface List
accès séquentiel : premier, suivant
insertions et suppressions efficaces
recherche lente, non efficace
Tableau dynamique = tableau + liste
class ArrayList
Paquetage java.util de Java
319
• Interface Collection
• Interfaces Set et List
• Méthodes
• boolean add(Object o)
• boolean remove(Object o)
• …
• Plusieurs implantations
• tableau : ArrayList
• liste chaînée : LinkedList
Collection
Set
List
ArrayList
LinkedList
• Algorithmes génériques : tri, maximum, copie ...
 méthodes statiques de Collection
Collection : méthodes communes
boolean add(Object) : ajouter un élément
boolean addAll(Collection) : ajouter plusieurs éléments
void clear() : tout supprimer
boolean contains(Object) : test d'appartenance
boolean containsAll(Collection) : appartenance collective
boolean isEmpty() : test de l'absence d'éléments
Iterator iterator() : pour le parcours (cf Iterator)
boolean remove(Object) : retrait d'un élément
boolean removeAll(Collection) : retrait de plusieurs éléments
boolean retainAll(Collection) : intersection
int size() : nombre d'éléments
Object[] toArray() : transformation en tableau
Object[] toArray(Object[] a) : tableau de même type que a
320
Exemple : ajout d’éléments
import java.util.*;
public class MaCollection {
static final int N = 25000;
List listEntier = new ArrayList();
public static void main(String args[]) {
MaCollection c = new MaCollection();
int i;
for (i = 0; i < N; i++) {
c.listEntier.add(new Integer(i));
}
}
}
321
Caractéristiques des collections
• Ordonnées ou non
322
interface Set
• Ordre sur les éléments ? voir tri
• Doublons autorisés ou non
interface SortedSet
• liste (List) : avec doubles
• ensemble (Set) : sans doubles
• Besoins d’accès
• indexé
• séquentiel, via Iterator
interface Collection
public Iterator iterator()
interface List
... get(int index)
... set(int index,Object o)
Fonctionnalités des Listes
323
Implantent l'interface List
ArrayList
 Liste implantée dans un tableau
 accès immédiat à chaque élément
 ajout et suppression lourdes
LinkedList
 accès aux éléments lourd
 ajout et suppression très efficaces
 permettent d'implanter les structures FIFO (file) et LIFO (pile)
 méthodes supplémentaires : addFirst(), addLast(),
getFirst(), getLast(), removeFisrt(),
removeLast()
Fonctionnalités des ensembles
Implantent l'interface Set
Eléments non dupliqués
HashSet
 table de hashage
 utiliser la méthode hashCode()
 accès très performant aux éléments
TreeSet
 arbre binaire de recherche
 maintient l'ensemble trié en permanence
 méthodes supplémentaires
 first() (mini), last() (maxi), subSet(deb,fin), headSet(fin),
tailSet(deb)
324
Recherche d’un élément
325
Méthode
 public boolean contains(Object o)
interface Collection, redéfinie selon les sous-classes
Utilise l’égalité entre objets
égalité définie par boolean equals(Object o)
par défaut (classe Object) : égalité de références
à redéfinir dans chaque classe d’éléments
Cas spéciaux
 doublons : recherche du premier ou de toutes les occurrences ?
 structures ordonnées : plus efficace, si les éléments sont
comparables (voir tri)
Tri d’une structure collective
326
Algorithmes génériques
Collections.sort(List l)
Arrays.sort(Object[] a,…)
Condition : collection d’éléments dont la classe définit des
règles de comparaison
en implémentant l’interface java.lang.Comparable
implements Comparable
en définissant la méthode de comparaison
public int compareTo(Object o)
 a.compareTo(b) == 0 si a.equals(b)
 a.compareTo(b) < 0 pour a strictement inférieur à b
 a.compareTo(b) > 0 pour a strictement supérieur à b
Généricité des algorithmes
• N'utiliser que les méthodes communes
• Déclaration
• Collection col = new ArrayList();
• Parcours des éléments de la collection : Iterator
•
•
•
•
accès indexé pas toujours disponible (méthode get())
utiliser la méthode Iterator iterator()
se déplacer avec les méthodes next() et hasNext()
exemple
Collection col = new TreeSet();
Iterator i = col.iterator();
while (i.hasNext())
traiter ((transtypage)i.next());
327
Vue d'ensemble des collections
• Hiérarchie simplifiée
328
329
Téléchargement