05.03.2014 Views

Le langage JAVA - IPNL

Le langage JAVA - IPNL

Le langage JAVA - IPNL

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Le</strong> <strong>langage</strong> <strong>JAVA</strong><br />

G. Baulieu Institut de Physique Nucléaire de Lyon – Septembre 2009


Quelques acronymes<br />

●<br />

●<br />

●<br />

●<br />

●<br />

JDK : Java Development Kit<br />

SDK : Software Development Kit<br />

J2SE : Java 2 Standard Edition<br />

JRE : Java Runtime Environment<br />

API : Application Programming Interface


Points forts<br />

●<br />

●<br />

●<br />

●<br />

●<br />

Simplicité : syntaxe ~C++ simplifié (pointeurs,<br />

fichiers d'entête, surcharge des opérateurs...)<br />

Orienté objet<br />

Fiabilité : gestion de la mémoire, compilateur<br />

puissant<br />

Portabilité : executable sur plusieurs systèmes<br />

Bibliothèque importante et documentée


Naissance de Java<br />

Java est un <strong>langage</strong> très récent...<br />

● 1991 : Projet Green (P. Naughton/J. Gosling – Sun)<br />

Langage Oak<br />

● 1996 : Java 1.0 – Premiere version officielle<br />

● 2004 : JDK 1.5 "Java 5.0"<br />

● 2006 : JDK 1.6 "Java 6.0"


La machine virtuelle<br />

Code source<br />

Compilation<br />

Bytecode (pseudo­code)<br />

Indépendant du<br />

système<br />

Interprétation<br />

Machine Virtuelle<br />

Génération<br />

Dépendant du<br />

système<br />

Langage machine


Notions fondamentales<br />

1. Premiers pas<br />

1. Structure d'un programme<br />

2. Compilation / Execution<br />

3. Localisation des classes<br />

2. Types de données<br />

3. Déclaration de variables<br />

4. <strong>Le</strong>s tableaux<br />

5. <strong>Le</strong>s opérateurs<br />

7. <strong>Le</strong>s structures de contrôle<br />

1. Conditions (IF)<br />

2. Boucles (FOR, WHILE, DO...WHILE)<br />

3. SWITCH<br />

4. Interruption de boucle<br />

8. <strong>Le</strong>s méthodes<br />

1. Généralités<br />

2. La méthode "main"<br />

6. <strong>Le</strong>s conversions de type


1.1 Structure d'un programme<br />

Fichier PremiereClasse.java<br />

/*<br />

Premier exemple de programme<br />

*/<br />

public class PremiereClasse<br />

{<br />

// Fonction principale<br />

public static void main(String[] args)<br />

{<br />

System.out.println("Premier programme!");<br />

}<br />

}<br />

Commentaires<br />

entre /* et */<br />

ou ligne précédée de //<br />

Déclaration de<br />

la classe<br />

Fonction<br />

principale


1.2 Compilation d'un programme<br />

●<br />

<strong>Le</strong> fichier doit porter le nom de la classe<br />

Dans notre exemple : PremiereClasse.java<br />

● Compilation :<br />

$ javac PremiereClasse.java<br />

Génère un fichier PremiereClasse.class<br />

● Execution :<br />

$ java PremiereClasse


1.3 Localisation des classes<br />

●<br />

●<br />

Par défaut : uniquement le répertoire courant<br />

Ajout de répertoires<br />

– Par l'option ­classpath :<br />

$ java ­classpath ./classes/ PremiereClasse<br />

– Par la variable d'environnement CLASSPATH :<br />

$ export CLASSPATH=./classes/<br />

$ java PremiereClasse


2. Types de données<br />

●<br />

●<br />

Java est un <strong>langage</strong> fortement typé<br />

8 types primitifs:<br />

– Entiers<br />

byte 8 bits -128 à 127<br />

short 16 bits -32 768 à 32 767<br />

int 32 bits -2 147 483 648 à 2 147 483 647<br />

-9 223 372 036 854 775 808<br />

long 64 bits à<br />

9 223 372 036 854 775 807


2. Types de données (2)<br />

– Virgule flottante<br />

float 32 bits 6 décimales significatives<br />

double 64 bits 15 chiffres significatifs<br />

– <strong>Le</strong> type char (16 bits)<br />

Une unité de code UTF­16<br />

– <strong>Le</strong> type boolean (1 bit)<br />

Deux valeurs : true et false<br />

Il n'existe pas de type chaîne de caractères. On utilisera la<br />

classe String.


3. Déclaration de variable<br />

●<br />

Indication du type suivi du nom de la variable:<br />

●<br />

●<br />

int compteur;<br />

double aire;<br />

La variable doit ensuite être initialisée:<br />

compteur = 0;<br />

aire = 3.54;<br />

On peut déclarer et initialiser une variable dans la même<br />

instruction:<br />

int compteur = 0;<br />

● <strong>Le</strong> mot clé final permet de déclarer une constante :<br />

final int COMPTEUR = 0;


4. <strong>Le</strong>s tableaux<br />

●<br />

●<br />

Structure permettant de stocker une série de valeurs du même type.<br />

Déclaration et initialisation:<br />

int[] tab;<br />

tab = new int[10];<br />

­> déclare la variable tab et lui alloue l'espace mémoire pour 10<br />

valeurs de type int.<br />

Remarque : "int tab[]" est également valable.<br />

●<br />

Affectation:<br />

tab[5] = 3;<br />

­> Affecte la valeur 3 à la sixième case du tableau (l'indice commence à 0!).


4. <strong>Le</strong>s tableaux (2)<br />

● <strong>Le</strong>cture :<br />

int i = tab[5];<br />

­> La variable i contient la valeur de la sixième case du<br />

tableau.<br />

●<br />

Raccourci:<br />

int[] tab = {3,24,5,3,6,54,7,1,6,45};<br />

­> Déclare, initialise et affecte les valeurs au tableau tab.


4. <strong>Le</strong>s tableaux (3)<br />

●<br />

Taille du tableau:<br />

int taille = tab.length;<br />

●<br />

Copie d'un tableau :<br />

– Copie de la variable :<br />

int[] secondArray = tab;<br />

secondArray[0] = 33;//tab[0] vaut 33!!!<br />

– Utilisation de la fonction arraycopy(from,fromIdx,to, toIdx, count)<br />

int[] secondArray = new int[5];<br />

System.arraycopy(tab, 0, secondArray, 0, 5);//copie les 5 premiers<br />

éléments de tab dans secondArray – attention à la taille de<br />

secondArray!<br />

●<br />

Tri d'un tableau :<br />

int[] tab = {3,24,5,3,6,54,7,1,6,45};<br />

java.util.Arrays.sort(tab);//tab contient maintenant<br />

{1,3,3,5,6,6,7,24,45,54}


5. Opérateurs<br />

● Affectation : =<br />

● Addition, soustraction et multiplication : +, ­, *<br />

● Division : /<br />

– Si appelé avec 2 entiers : division entière<br />

– Sinon division en virgule flottante<br />

●<br />

On peut combiner opérateurs arithmétiques et opérateurs<br />

d'affectation : +=, ­=, *= ...<br />

int n = 2;<br />

n += 3; // n vaut 5


5. Opérateurs (2)<br />

● Incrémentation, décrémentation : ++,­int<br />

m = 1;<br />

m++; //m vaut 2<br />

int n = 2;<br />

int a = 2 * ++m; //a vaut 6, m vaut 3<br />

int b = 2 * n++; //b vaut 4, n vaut 3<br />

● Opérateurs relationnels : ==, !=, >, =,


6. Conversions<br />

●<br />

●<br />

Si besoin, les valeurs peuvent être converties<br />

automatiquement :<br />

int i = 123;<br />

long l = i;<br />

Attention : dans certains cas cela peut entraîner une perte<br />

de précision:<br />

– int vers float<br />

– long vers float<br />

– long vers double


6. Conversions (2)<br />

● On peut faire une conversion explicite :<br />

double d = 4.321;<br />

int i = (int)d; // i vaut 4<br />

Autre exemple :<br />

int i=3;<br />

double d1 = 5/i; // d1 vaut 1.0 !<br />

double d2 = 5/(double)i; // d2 vaut 1.6667


7.1 Conditions ­ IF<br />

●<br />

Syntaxe de l'instruction conditionnelle:<br />

if (condition) instruction<br />

– La condition est une expression booléenne, indiquée entre<br />

parenthèses.<br />

– L'instruction peut être unique, ou on peut en placer plusieurs dans<br />

un bloc d'instructions (instructions entre accolades).<br />

●<br />

Exemples<br />

if(x


7.1 Conditions(2) ­ ELSE<br />

●<br />

●<br />

●<br />

Instruction else:<br />

if (condition) instruction1 else instruction2<br />

if(x


7.2 <strong>Le</strong>s boucles ­ FOR<br />

●<br />

Boucle gérée par un compteur:<br />

for(initialisation;test;mise à jour)<br />

instruction(s);<br />

● Exemple :<br />

for (int i=0;i Affiche les valeurs de i de 0 à 9.


7.2 <strong>Le</strong>s boucles (2) – FOR EACH<br />

●<br />

●<br />

Simplification pour les tableaux et collections<br />

Version classique ('tab' est un tableau de doubles):<br />

for (int i=0;i


7.2 <strong>Le</strong>s boucles (3) ­ WHILE<br />

●<br />

Boucle tant que la condition est vraie.<br />

while(condition)<br />

instruction(s);<br />

● Exemple :<br />

while(nbSucre


7.2 <strong>Le</strong>s boucles (4) ­ DO...WHILE<br />

●<br />

Répète l'instruction jusqu'à ce que la condition soit vraie.<br />

do<br />

instuction(s);<br />

while(condition);<br />

<strong>Le</strong>s instructions sont exécutées au moins une fois.<br />

●<br />

Exemple<br />

do{<br />

}<br />

System.out.println("Saisir une valeur positive : ");<br />

//affectation d'une valeur saisie par l'utilisateur<br />

dans la variable double "reponse"<br />

while(reponse


7.3 L'instruction SWITCH<br />

●<br />

Permet de gérer les différentes valeurs prisent par une<br />

variable entière.<br />

● Syntaxe :<br />

switch(variable){<br />

case 1:<br />

}<br />

...<br />

break;<br />

case 2:<br />

...<br />

break;<br />

default:<br />

...<br />

break;


7.4 Interruption de boucle<br />

●<br />

L'instruction break permet de sortir immédiatement d'une<br />

boucle.<br />

●<br />

L'instruction continue court circuite la fin de boucle.<br />

while(true){<br />

...<br />

if(stop)<br />

}<br />

break;<br />

...<br />

if(shortcut)<br />

continue;<br />

...


7.4 Interruption de boucle (2)<br />

●<br />

On peut également sortir de boucles imbriquées en utilisant<br />

un label:<br />

label_name:<br />

while(...){<br />

...<br />

while(...){<br />

}<br />

}<br />

if(stop)<br />

break label_name; // sort des boucles<br />

...<br />

... à utiliser avec parcimonie...


8.1 <strong>Le</strong>s méthodes<br />

●<br />

Une méthode est une suite d'instructions permettant de<br />

réaliser des traitements sur les données.<br />

● Déclaration :<br />

type_de_retour Nom(liste d'arguments){<br />

Corps_de_la_méthode<br />

return valeur_de_retour<br />

}<br />

int addition(int a, int b){<br />

int resultat = a+b;<br />

return resultat;<br />

}<br />

Si la méthode ne retourne rien, on utilise le type de retour void.<br />

● Appel de la méthode :<br />

int somme = addition(3,5);//somme vaut 8 après l'appel


8.2 La méthode main<br />

●<br />

●<br />

●<br />

Point d'entrée dans le programme (obligatoire!)<br />

Prototype:<br />

public static void main(String[] args)<br />

{<br />

...<br />

}<br />

<strong>Le</strong> tableau args contient les arguments passés dans la ligne de<br />

commande :<br />

1er argument : args[0]<br />

2ème argument : args[1] ...


Programmation orientée objet<br />

1. Introduction<br />

1. Vocabulaire<br />

2. Exemple : la classe Color<br />

3. Utilisation des paquetages<br />

4. La classe String<br />

3. Ajouter une classe dans un paquetage<br />

4. Documenter le code : <strong>JAVA</strong>DOC<br />

5. <strong>Le</strong>s fichiers JAR<br />

6. Un outil de construction : ANT<br />

5. <strong>Le</strong>s classes Integer, Double...<br />

2. Création d'une classe<br />

1. <strong>Le</strong>s champs<br />

2. <strong>Le</strong>s constructeurs<br />

3. Libération de la mémoire<br />

4. <strong>Le</strong>s méthodes<br />

5. <strong>Le</strong> mot clé this<br />

6. L'instruction static


1. Introduction<br />

●<br />

●<br />

Décomposer le programme en modules indépendants : les<br />

objets.<br />

Chaque objet contient sa structure de données (les<br />

champs) et les traitements possibles sur ces données (les<br />

méthodes).<br />

Modifier la structure des données ou<br />

le traitement de celles­ci ne modifie<br />

pas le programme général.


1.1 Vocabulaire<br />

●<br />

●<br />

●<br />

Une classe contient la description des données d'un objet<br />

ainsi que les traitements pouvant être effectués sur celui­ci<br />

(= le moule).<br />

On peut ensuite créer une ou plusieurs "instance(s) de la<br />

classe" (= les biscuits).<br />

<strong>Le</strong>s données de l'objet ne seront pas accessibles à<br />

l'utilisateur : c'est l'encapsulation.<br />

Si les données de l'objet sont incohérentes, l'erreur est<br />

obligatoirement dans la classe! Nul besoin d'aller chercher<br />

partout dans le programme...


1.2 Exemple : la classe Color<br />

●<br />

L'API java met à notre disposition la classe java.awt.Color<br />

● Création d'une instance de la classe :<br />

java.awt.Color maCouleur = new java.awt.Color(255,255,255);//Création<br />

d'une instance contenant la couleur blanche


1.3 Interlude : <strong>Le</strong>s paquetages<br />

● But :<br />

– Structurer les classes<br />

– Faciliter la recherche d'une classe<br />

– Eviter les confusions entre classes de même nom<br />

– Modifier la visibilité d'une classe


1.3 L'instruction import<br />

●<br />

Permet de créer un raccourci pour faire référence aux<br />

classes d'un paquetage:<br />

import java.awt.Color;<br />

class [...]{<br />

[...]<br />

Color maCouleur = new Color(255,255,255);<br />

● On peut également utiliser :<br />

import java.awt.*;<br />

...pour pouvoir accéder à toutes les classes du paquetage<br />

java.awt.


1.2 Exemple : la classe Color(2)<br />

●<br />

On peut créer différentes instances de la même classe:<br />

Color blanc = new Color(255,255,255);<br />

Color rouge = new Color(255,0,0);<br />

<strong>Le</strong>s 2 objets ont une existence propre!<br />

●<br />

On peut appeler différentes méthodes sur les objets:<br />

int valeurRouge = rouge.getRed(); // valeurRouge vaut 255<br />

Appel de la méthode getRed() appartenant à la classe Color<br />

sur l'objet 'rouge'.


1.2 Exemple : la classe Color(3)<br />

● <strong>Le</strong> programme suivant :<br />

Color rouge = new Color(255,0,0);<br />

System.out.println(rouge);<br />

Color rougeSombre = rouge.darker();<br />

System.out.println(rougeSombre);<br />

● Affiche :<br />

java.awt.Color[r=255,g=0,b=0]<br />

java.awt.Color[r=178,g=0,b=0]<br />

●<br />

Comment connaître les méthodes d'une classe?<br />

Grâce à la documentation de la classe!<br />

http://java.sun.com/j2se/1.5.0/docs/api/


1.2 Exemple : la classe Color(4)


1.4 La classe String<br />

● Déclaration :<br />

String vide = new String(""); // ou String vide = "";<br />

String exemple = "Chaine de caractères";<br />

● Longueur :<br />

int taille = exemple.length();<br />

● Concaténation :<br />

String nouvelleChaine = "Exemple d'une "+exemple;<br />

● Sous chaines :<br />

String petiteChaine = exemple.substring(0,7);<br />

● Egalité :<br />

boolean sontEgales = exemple.equals("test");


1.5 Classes Integer, Double...<br />

Il est parfois utile de pouvoir utiliser les types de base comme des<br />

objets. L'API Java dispose de classes wrapper:<br />

Integer objectInt = new Integer(5);<br />

La conversion est faite automatiquement :<br />

int i = objectInt; //equivalent à objectInt.intValue()<br />

Ces classes permettent aussi la conversion de chaines de<br />

caractères :<br />

int i = Integer.parseInt(“234”);


2. Création d'une classe<br />

● Une classe est composée :<br />

● De champs : données propres à l'objet.<br />

● De constructeurs : méthodes permettant d'instancier un<br />

objet (création de l'objet).<br />

● De methodes : services offerts par la classe pour<br />

manipuler l'objet.


2.1 <strong>Le</strong>s champs de la classe<br />

●<br />

Ce sont les données qui seront contenues dans une<br />

instance de la classe.<br />

●<br />

Déclaration:<br />

class Personne{<br />

private String nom;<br />

private String prenom;<br />

...<br />

}


2.1 <strong>Le</strong>s champs de la classe (2)<br />

Portée des champs :<br />

●<br />

private indique que le champ n'est accessible que de l'intérieur<br />

de la classe (encapsulation).<br />

On pourrait (mais on ne le veut probablement pas!) déclarer les<br />

champs:<br />

●<br />

●<br />

public : toujours visible par tous.<br />

protected : visible pour le paquetage et les classes filles (voire<br />

héritage).<br />

<strong>Le</strong>s méthodes de la classe utilisent les mêmes modificateurs de<br />

visibilité.


2.1 <strong>Le</strong>s champs de la classe (3)<br />

●<br />

Initialisation explicite<br />

On peut initialiser les champs de la classe au moment de la déclaration :<br />

class Personne{<br />

private String nom = "";<br />

private String prenom = "";<br />

...<br />

}<br />

Cette affectation est effectuée avant l'appel du constructeur.


2.2 <strong>Le</strong>s constructeurs<br />

●<br />

Méthode permettant d'instancier un objet.<br />

●<br />

<strong>Le</strong> constructeur alloue la mémoire pour les champs de<br />

l'objet et les initialise.<br />

●<br />

●<br />

<strong>Le</strong> constructeur est une méthode ayant le même nom que la<br />

classe :<br />

public Personne(){<br />

nom = "X";<br />

prenom = "Toto";<br />

}<br />

Cette méthode est appelée lors de l'instruction:<br />

Personne p = new Personne();


2.2 <strong>Le</strong>s constructeurs (2)<br />

●<br />

Si aucun constructeur n'est défini, java crée un constructeur<br />

par défaut (sans argument). Ce constructeur initialise les<br />

champs de la classe :<br />

– numérique : 0<br />

– booléen : false<br />

– classe : null (inexistant)<br />

Pour des raisons de lisibilité, il est préférable d'écrire<br />

explicitement un constructeur.


2.2 <strong>Le</strong>s constructeurs (3)<br />

●<br />

On peut définir plusieurs constructeurs pour une même classe<br />

(surcharge):<br />

public Personne(){<br />

nom = "X";<br />

prenom = "Toto";<br />

}<br />

public Personne(String n, String p){<br />

nom = n;<br />

prenom = p;<br />

}<br />

● Appel :<br />

Personne p1 = new Personne();// Toto X<br />

Personne p2 = new Personne("Dupont", "Jean");// Jean Dupont


2.3 Libération de la mémoire<br />

●<br />

●<br />

La libération de la mémoire est effectuée par java par<br />

l'intermédiaire du ramasse­miettes (garbage collector).<br />

Il n'y a donc pas de destructeurs.<br />

●<br />

Si une ressource doit absolument être libérée il faut<br />

explicitement appeler une méthode écrite dans ce but.


2.4 <strong>Le</strong>s méthodes de la classe<br />

●<br />

Fournissent des fonctionnalités à la classe.<br />

●<br />

<strong>Le</strong>s méthodes seront appelées par une instance de la<br />

classe :<br />

Personne p = new Personne();<br />

String nom = p.getNom();<br />

● Implémentation :<br />

public String getNom(){<br />

return nom;<br />

}


2.4 <strong>Le</strong>s méthodes de la classe (2)<br />

<strong>Le</strong>s méthodes d'une classe ont accès aux champs privés de la<br />

classe et peuvent donc les modifier.<br />

public void setNom(String n){<br />

}<br />

nom = n;<br />

Personne p = new Personne();<br />

p.setNom("Dupont");//impossible si setNom etait private !<br />

Rappel : une méthode peut être définie comme public, private ou<br />

protected<br />

Implémenter la méthode String toString() permet d'afficher l'objet avec<br />

System.out.println();<br />

Implémenter la méthode Object clone() permet de renvoyer une copie de<br />

l'objet.


2.5 <strong>Le</strong> mot clé this<br />

Fait référence à l'instance courante de la classe:<br />

void setNom(String nom){<br />

}<br />

this.nom = nom;<br />

Il peut également être utilisé pour appeler un constructeur<br />

depuis un autre constructeur :<br />

public Personne(){<br />

}<br />

this("Dupuis", "Paul"); // Premiere instruction!!<br />

// <strong>Le</strong> constructeur Personne(String, String) est appelé


2.6 L'instruction static<br />

●<br />

●<br />

●<br />

Permet de définir des variables et méthodes de classe.<br />

Une variable statique est commune à toutes les instances de la<br />

classe.<br />

Une méthode (ou une variable) statique peut être appelée sans<br />

instance, avec le nom de la classe :<br />

double r = Math.sqrt(81);// appel de la méthode statique sqrt()<br />

de la classe Math.<br />

●<br />

Une méthode statique ne peut accéder qu'aux champs<br />

statiques de la classe.


3. Ajouter une classe dans un<br />

paquetage<br />

● Syntaxe :<br />

package Formation.Java.Exemples;<br />

class MaClasse{...}<br />

La classe MaClasse se trouve dans le paquetage<br />

"Formation.java.Exemples" : le fichier MaClasse.class devra donc se<br />

trouver dans le répertoire :<br />

[...]/Formation/Java/Exemples/


4. Documenter le code : Javadoc<br />

●<br />

●<br />

Outil permettant de générer de la documentation à partir du<br />

code source.<br />

Nécessite des commentaires dans le code:<br />

Commentaires situés entre /** et */<br />

●<br />

Documentation d'une classe:<br />

/** Commentaire décrivant la classe.<br />

@version 1.0<br />

@author Jules Dupont<br />

*/<br />

public class MaClasse {...}


4. Javadoc (2)<br />

●<br />

Documentation d'un méthode:<br />

/** Commentaire décrivant la méthode.<br />

@param a Description de l'argument a<br />

@param b Description de l'argument b<br />

@return <strong>Le</strong> résultat de la méthode<br />

*/<br />

public int addition(int a, int b){...}<br />

●<br />

Génération:<br />

% javadoc ­author ­version ­d ./doc/ MaClasse.java


4. Javadoc (3)<br />

http://java.sun.com/j2se/javadoc/


5. Créer une archive : les<br />

fichiers JAR<br />

●<br />

●<br />

●<br />

Java ARchive<br />

Permet de stocker tous les fichiers (.class, images, sons...)<br />

dans un seul fichier.<br />

Peut être compressé.<br />

● Création de l'archive :<br />

% jar cf NomArchive.jar Fichiers


5. <strong>Le</strong>s fichiers JAR (2)<br />

●<br />

On peut ajouter un fichier MANIFEST.MF qui contient des<br />

informations sur l'archive :<br />

Manifest­Version: 1.0<br />

Main­Class: Formation/MaClasse<br />

●<br />

Création de l'archive:<br />

% jar cfm NomArchive.jar MANIFEST.MF Fichiers<br />

● On peut alors lancer le programme par la commande :<br />

% java ­jar NomArchive.jar


6. Un outils de construction :<br />

ANT<br />

●<br />

●<br />

●<br />

Il est fastidieux de devoir taper de longues commandes à<br />

chaque modification.<br />

Dans un projet conséquent, il peut y avoir plusieurs<br />

commandes à exécuter pour compiler, créer des archives,<br />

générer la documentation, créer une distribution...<br />

ANT (~make) permet de simplifier ces procédures en<br />

définissant des taches pouvant dépendre les une des<br />

autres.


6. Un outils de construction :<br />

ANT (2)<br />

– On défini des taches dans le fichier build.xml :<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

– On peut ensuite exécuter une tache avec la commande :<br />

% ant nom_de_la_tache<br />

Exemple : % ant compile


L'héritage<br />

1. Introduction<br />

1. Concept<br />

2. Exemple<br />

2. Syntaxe<br />

6. <strong>Le</strong>s interfaces<br />

1. Utilisation<br />

2. Création<br />

7. <strong>Le</strong> clonage<br />

1. <strong>Le</strong> mot clé extends<br />

2. <strong>Le</strong>s constructeurs<br />

3. <strong>Le</strong>s méthodes<br />

4. Interdire l'héritage<br />

3. <strong>Le</strong> polymorphisme<br />

4. Classes et méthodes abstraites<br />

5. La classe Object


1.1 Concept<br />

●<br />

●<br />

●<br />

L'idée est de pouvoir créer de nouvelles classes à partir de<br />

classes existantes.<br />

Exprime la relation "est un". Par exemple, un lion est un<br />

animal : la classe 'Lion' peut donc hériter de la classe<br />

'Animal'. Elle dispose ainsi automatiquement de toutes les<br />

données et services de la classe 'Animal'.<br />

La classe 'Animal' est appelée classe mère ou superclasse<br />

et la classe 'Lion' classe fille ou sous­classe.


1.2 Exemple<br />

<strong>Le</strong> lion et l'oiseau sont des animaux : ils ont une taille, une couleur,<br />

peuvent manger et dormir.<br />

Seul le lion peut rugir et seul l'oiseau peut voler.<br />

On peut ajouter des champs spécifiques à la classe fille.


1.2 Exemple (2)<br />

● La classe Animal :<br />

import java.awt.Color;<br />

class Animal{<br />

private Color couleur;<br />

private int taille;<br />

public Animal(){...}<br />

public Animal(Color c, int t){...}<br />

}<br />

public void Manger(){...}<br />

public void Dormir(){...}<br />

public Color getCouleur(){...}<br />

public int getTaille(){...}


2.1 <strong>Le</strong> mot clé extends<br />

● On utilise le mot clé extends pour marquer l'héritage :<br />

class Lion extends Animal{<br />

private Color couleurCriniere;<br />

}<br />

public void Rugir(){...}<br />

public void setCouleurCriniere(Color c){...}<br />

public Color getCouleurCriniere(){...}<br />

● Utilisation :<br />

Lion leo = new Lion();<br />

leo.Rugir();<br />

leo.Dormir();<br />

On ne peut hériter que d'une seule classe!


2.2 <strong>Le</strong>s constructeurs<br />

● Constructeur par défaut :<br />

public Lion(){<br />

}<br />

super();<br />

couleurCriniere = new Color(125, 125, 125);<br />

<strong>Le</strong> mot clé super permet d'appeler un constructeur de la classe mère.<br />

● Autre constructeur :<br />

public Lion(Color c, int t, Color criniere){<br />

}<br />

super(c, t);<br />

couleurCriniere = new Color(criniere.getRed(), criniere.getGreen(),<br />

criniere.getBlue());<br />

L'appel au constructeur de la classe mère est toujours la première instruction du<br />

constructeur de la classe fille.


2.3 <strong>Le</strong>s méthodes<br />

●<br />

La classe fille hérite de toutes les méthodes de la classe mère. Par<br />

exemple si la classe Animal contient la méthode :<br />

public String toString(){<br />

}<br />

return "Je mesure "+taille+" cm et je suis de couleur "+couleur;<br />

On peut alors automatiquement écrire :<br />

String description = leo.toString(); // leo est une instance de Lion<br />

Je mesure X cm et je suis de couleur [color]"<br />

Ceci permet de réduire la taille du code à écrire... ou à corriger!<br />

Cependant on peut souhaiter spécialiser la méthode.


2.3 <strong>Le</strong>s méthodes (2) :<br />

Spécialisation<br />

●<br />

On peut redéfinir une méthode existante de la classe mère pour mieux<br />

l'adapter à la classe fille :<br />

public String toString(){<br />

}<br />

String description = "Je suis un lion avec une criniere<br />

"+CouleurCriniere+"\n";<br />

return description+super.toString();<br />

<strong>Le</strong> résultat de la méthode toString() de la classe Lion est alors différent de<br />

celui de la classe Animal :<br />

String description = leo.toString(); // leo est une instance de Lion<br />

"Je suis un lion avec une criniere [color]<br />

Je mesure X cm et je suis de couleur [color]"


2.4 Interdire l'heritage<br />

●<br />

Il est possible d'interdire à tout autre programmeur d'hériter de votre<br />

classe : on utilise alors le mot clé final.<br />

final class Lion extends Animal{...}<br />

... Il est maintenant impossible de créer une classe héritant de Lion.<br />

●<br />

De la même façon, on peut empêcher la redéfinition d'une méthode par<br />

les classe filles :<br />

public final String toString(){...} // Dans la classe mère<br />

Il est maintenant impossible aux classes filles de redéfinir la méthode<br />

toString().


3 <strong>Le</strong> polymorphisme<br />

L'héritage exprime la relation "est un". Dans notre exemple, un lion est<br />

un animal tout comme un oiseau l'est également. Il est donc logique de<br />

pouvoir écrire :<br />

Animal albert = new Lion();<br />

Animal gustave = new Oiseau();<br />

On peut ensuite appeler n'importe quelle méthode définie dans la classe<br />

Animal :<br />

System.out.println(albert.toString());<br />

System.out.println(gustave.toString());<br />

Dans ce cas, le compilateur va créer une liaison dynamique permettant<br />

de choisir la méthode au moment de l'execution :<br />

System.out.println(albert.toString()); // méthode Lion.toString()<br />

System.out.println(gustave.toString()); // méthode Oiseau.toString()


3 <strong>Le</strong> polymorphisme (2)<br />

On peut naturellement définir un tableau :<br />

Animal[] animaux = new Animal[2];<br />

animaux[0] = new Lion();<br />

animaux[1] = new Oiseau();<br />

et afficher le contenu de ce tableau :<br />

for(Animal a : animaux){<br />

System.out.println(a); // méthode toString()<br />

}<br />

"Je suis un lion avec une criniere [color]<br />

Je mesure X cm et je suis de couleur [color]<br />

Je suis un oiseau<br />

Je mesure X cm et je suis de couleur [color]"


3 <strong>Le</strong> polymorphisme (3)<br />

Ayant un tableau d'objets 'Animal', on ne peut appeler que les méthodes<br />

de la classe Animal :<br />

animaux[0].Dormir(); // OK<br />

animaux[0].Rugir(); // NON!! N'existe pas dans la classe Animal!<br />

Si on veux pouvoir utiliser toutes les fonctionalités de la classe, on doit<br />

effectuer un transtypage :<br />

((Lion)animaux[0]).Rugir(); // Compilation OK<br />

Par contre rien ne prouve que animaux[0] soit une instance de Lion. On<br />

peut donc avoir une erreur à l'execution! Pour l'éviter :<br />

if(animaux[O] instanceof Lion)<br />

((Lion)animaux[0]).Rugir(); // Uniquement si on a un Lion !


Classes abstraites<br />

4 Classes et méthodes<br />

abstraites<br />

A mesure que l'on élabore la hiérarchie des classes, certaines peuvent<br />

ne plus décrire des objets réels. Pour notre exemple, la classe 'Animal'<br />

correspond elle à un objet utile, ou simplement à un concept abstrait?<br />

Il est possible de déclarer une classe comme "abstraite", ceci aura 2<br />

conséquences :<br />

● Il n'est plus possible de créer une instance de la classe.<br />

● La classe peut comporter des méthodes abstraites.<br />

Méthodes abstraites<br />

Une méthode abstraite est déclarée dans la classe mère mais n'est<br />

implémentée que dans les classes filles.


4 Classes et méthodes<br />

Déclaration d'une classe abstraite :<br />

abstract class Animal{...}<br />

abstraites (2)<br />

Déclaration d'une méthode abstraite :<br />

public abstract String toString(); // pas d'implémentation<br />

Conséquence : toutes les classes héritant de Animal, si elles ne sont pas<br />

abstraites elles­même, doivent implémenter la méthode toString().


5 La classe Object<br />

Si une classe n'hérite pas explicitement d'une autre, alors elle<br />

hérite de la classe Object.<br />

Par conséquent, toutes les classes java héritent directement<br />

ou indirectement de la classe Object.<br />

Il est donc toujours possible d'écrire :<br />

Object o = new NomDeLaClasse(...);


5 La classe Object (2)<br />

La classe Object propose différentes méthodes dont vont<br />

hériter toutes les classes java:<br />

– String toString() : retourne une description de la<br />

classe.<br />

– boolean equals() : comparaison de deux objets<br />

– Object clone() : retourne une copie de l'objet<br />

Ces méthodes doivent souvent être redéfinies au niveau de la<br />

classe pour être pertinentes.<br />

Voire la documentation de la classe Object pour la liste complète des méthodes...


6.1 <strong>Le</strong>s interfaces ­ Utilisation<br />

Une interface est un ensemble de règles auxquelles doit se<br />

conformer une classe. C'est une sorte de cahier des charges.<br />

Exemple : La méthode sort() de la classe Arrays permet de<br />

trier un tableau d'objets.<br />

Condition : les objets doivent provenir d'une classe qui<br />

implémente l'interface Comparable :<br />

public interface Comparable<br />

{<br />

}<br />

int compareTo(T other);


6.1 <strong>Le</strong>s interfaces – Utilisation<br />

(2)<br />

Modifons la classe Animal pour implementer l'interface Comparable :<br />

class Animal implements Comparable{// on peut implémenter plusieurs interfaces<br />

[...]<br />

public int compareTo(Animal other){<br />

}<br />

}<br />

if (taille>other.taille) return 1;<br />

if (taille


6.1 <strong>Le</strong>s interfaces – Utilisation<br />

(3)<br />

Quelques propriétés des interfaces :<br />

– Elles ne peuvent pas contenir de champs, mais elles peuvent<br />

contenir des constantes<br />

– Elles ne peuvent pas être instanciées<br />

– On peut cependant déclarer des variables interfaces (ces variables<br />

références des objets de classes implémentant l'interface)<br />

– Une interface peut hériter d'une autre interface<br />

– Une classe peut implémenter plusieurs interfaces


6.2 <strong>Le</strong>s interfaces – Création<br />

Ecrire une interface est très simple, il suffit de lui donner un nom et<br />

d'énumérer les méthodes.<br />

Par exemple, nous pouvons créer une interface Dessinable qui garantit<br />

que les classes l'implémentant auront une méthode public void<br />

Dessine(Graphics g) :<br />

public interface Dessinable {<br />

}<br />

public void Dessine(Graphics g);<br />

Comme pour une classe, ce code devra être placé dans un fichier nommé<br />

Dessinable.java.


7 <strong>Le</strong> clonage<br />

<strong>Le</strong> clonage permet d'obtenir une copie en profondeur d'un objet par<br />

un appel à la méthode clone().<br />

Cependant cette méthode est protected dans la classe Object!<br />

Il faut donc la redéfinir dans la classe fille :<br />

public Object clone() throws CloneNotSupportedException{<br />

Personne p = (Personne)super.clone();<br />

p.birthday = (Date)this.birthday.clone();<br />

return p;<br />

}


7 <strong>Le</strong> clonage (2)<br />

Afin d'éviter une erreur lors du clonage (une classe fille qui ne<br />

redéfinit pas correctement la méthode clone()), il est impératif<br />

d'implémenter l'interface Cloneable pour indiquer que notre classe<br />

gère le clonage. C'est une interface de balisage (elle ne contient<br />

aucune méthode).<br />

class Personne implements Cloneable{<br />

...<br />

}<br />

Tout appel à la méthode clone() à partir d'une classe<br />

n'implémentant pas Cloneable générera une exception<br />

CloneNotSupportedException.


Gestion des exceptions<br />

1.Envoi d'une exception<br />

2.Réception d'une exception<br />

3.<strong>Le</strong> mot clé finally<br />

4.Créer ses propres exceptions


1. Envoi d'une exception<br />

Si une méthode rencontre une situation qu'elle ne sait pas gérer,<br />

elle peut envoyer une exception.<br />

public void openFile(String name) throws<br />

FileNotFoundException{<br />

}<br />

[...le fichier n'existe pas]<br />

throw new FileNotFoundException();<br />

[...]<br />

Lors de l'envoi d'une exception, on sort de la méthode<br />

immédiatement. Celle­ci ne retourne pas de valeur.


2. Réception d'une exception<br />

La méthode pouvant envoyer une exception doit être appelée à<br />

l'interieur d'un bloc try...catch:<br />

try{<br />

}<br />

...<br />

openFile(fileName);<br />

...<br />

catch(FileNotFoundException e){<br />

}<br />

System.out.println(“Aucun fichier trouvé!”);<br />

Si exception<br />

On peut enchaîner plusieurs blocs catch pour gérer plusieurs types<br />

d'exception.


3. <strong>Le</strong> mot clé finally<br />

On peut également utiliser un block finally qui sera executé qu'une<br />

exception soit levée ou non :<br />

try{<br />

}<br />

openFile(fileName);<br />

catch(FileNotFoundException e){...}<br />

catch(...){...}<br />

finally{...}<br />

<strong>Le</strong> bloc finally est exécuté :<br />

– soit après le bloc try si aucune exception n'est envoyée<br />

– soit après l'un des blocs catch si une exception a été envoyée.<br />

– même si une instruction return a été rencontrée.


4. Créer ses propres exceptions<br />

Pour créer une nouvelle classe pouvant être utilisée comme<br />

exception, il suffit d'hériter de la classe Exception ou d'une de ses<br />

classes filles:<br />

public class MyException extends Exception {<br />

}<br />

public MyException(){}<br />

public MyException(String message) {<br />

}<br />

super(message);<br />

On pourra maintenant utiliser la classe MyException de la même facon<br />

que la classe FileNotFoundException.<br />

<strong>Le</strong> compilateur force le traitement des exceptions sauf pour les<br />

RuntimeException.


Introduction aux interfaces<br />

graphiques<br />

1. AWT et Swing<br />

2. <strong>Le</strong>s classes de base<br />

1. Créer une fenêre : JFrame<br />

2. Ajouter un contenu : JPanel<br />

3. JLabel<br />

4. JTextField<br />

5. JButton<br />

6. Autres composants<br />

3. Gestion des événements<br />

1. Créer un écouteur<br />

2. Classes internes<br />

3. Lier un composant à un écouteur<br />

4. Interfaces listener utiles


1. AWT et Swing<br />

●<br />

Abstract Window Toolkit (AWT) : première bibliothèque graphique<br />

de Java<br />

Appel des fonctions natives du système d'exploitation<br />

La bibliothèque AWT est contenue dans la package java.awt.*<br />

●<br />

Swing : Standard depuis Java 2<br />

Dessine tous les composants dans une fenêtre<br />

La bibliothèque Swing est contenue dans la package javax.Swing.*


2.1 Créer une fenêtre : JFrame<br />

La classe JFrame permet de créer une fenêtre graphique :<br />

import javax.swing.*;<br />

public class MyFrame extends JFrame {<br />

public static final int HEIGHT = 250;<br />

public static final int WIDTH = 300;<br />

public MyFrame(String title){<br />

super(title);//constructeur de JFrame<br />

setSize(WIDTH, HEIGHT);<br />

}}<br />

public class Launcher{<br />

public static void main(String args[]){<br />

}}<br />

MyFrame mf = new MyFrame("Nom de la fenetre");<br />

mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />

mf.setVisible(true);


2.1 Créer une fenêtre : JFrame<br />

(2)<br />

JFrame : fonctions utiles<br />

– setTitle(String t) : donne un titre à la fenêtre.<br />

– setSize(int w, int h) : stipule la taille de la fenêtre en pixels.<br />

– setLocation(int x, int y) : stipule l'emplacement de la fenêtre.<br />

– setDefaultCloseOperation(constante) : comportement du<br />

programme lors de la fermeture de la fenêtre.<br />

– setVisible(boolean b) : affiche ou cache la fenêtre.<br />

– getContentPane() : retourne la couche "contenu" de la<br />

fenêtre.


2.2 Ajouter un contenu : JPanel<br />

Un JPanel est un composant sur lequel on peut dessiner et qui peut egalement<br />

contenir d'autres composants. Pour déssiner sur un JPanel, il faut surcharger la<br />

méthode void paintComponent(Graphics g).<br />

import javax.swing.*;import java.awt.*;<br />

public class MyPanel extends JPanel {<br />

public void paintComponent(Graphics g){<br />

}}<br />

super.paintComponent(g);<br />

g.fillRect(20,20,25,50);<br />

public class Launcher{<br />

public static void main(String args[]){<br />

}}<br />

MyFrame mf = new MyFrame("Nom de la fenetre");<br />

mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />

mf.getContentPane().add(new MyPanel());<br />

mf.setVisible(true);


2.2 Ajouter un contenu : JPanel<br />

(2)<br />

Pour ajouter d'autres composants dans un JPanel, on lui affecte un<br />

gestionnaire de mise en forme. On dispose de plusieurs<br />

gestionnaires possibles :<br />

– FlowLayout (défaut de JPanel) : Tous les composants sont ajoutés<br />

horizontalement jusqu'à ce qu'il n'y ait plus de place sur la ligne, on<br />

commence alors une nouvelle ligne.<br />

– BorderLayout (défaut de JFrame) : L'espace est divisé en 5 zones<br />

(Nord, Sud, Est, Ouest, Centre) et on doit affecter les composants à<br />

l'une de ces zones.<br />

– GridLayout : On divise l'espace en lignes et colonnes, un composant<br />

est affecté à la case (x,y).<br />

– GridBagLayout : Similaire à GridLayout, mais les cases peuvent<br />

avoir des tailles différentes.<br />

http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html


2.3 JLabel<br />

Un JLabel est un composant permettant d'afficher du texte qui ne pourra pas<br />

être modifié par l'utilisateur.<br />

import javax.swing.*;<br />

import java.awt.*:<br />

public class MyInterface{<br />

private JLabel titre;<br />

public MyInterface(){<br />

}}<br />

MyFrame mf = new MyFrame("Nom de la fenetre");<br />

mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />

JPanel j = new JPanel();<br />

j.setLayout(new BorderLayout());//definition du gestionnaire<br />

titre = new JLabel("Un titre pour la fenetre", JLabel.CENTER);<br />

j.add(titre, BorderLayout.NORTH);<br />

mf.getContentPane().add(j);<br />

mf.setVisible(true);


2.4 JTextField<br />

Un JTextField est un composant permettant à l'utilisateur de saisir du texte.<br />

public class MyInterface{<br />

private JLabel titre;<br />

private JTextField text;<br />

public MyInterface{<br />

MyFrame mf = new MyFrame("Nom de la fenetre");<br />

JPanel mainPanel = new JPanel();<br />

mainPanel.setLayout(new BorderLayout());//definition du gestionnaire<br />

titre = new JLabel("Saisir puis valider : ", JLabel.CENTER);<br />

text = new JTextField(10);<br />

JPanel saisiePanel = new JPanel();<br />

saisiePanel.add(titre);<br />

saisiePanel.add(text);<br />

mainPanel.add(saisiePanel, BorderLayout.NORTH);<br />

mf.getContentPane().add(mainPanel);<br />

mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />

mf.setVisible(true);<br />

}}


2.5 JButton<br />

Un JButton permet d'afficher un bouton sur lequel l'utilisateur pourra cliquer.<br />

private JLabel titre;<br />

private JTextField text;<br />

private JButton bouton;<br />

public MyInterface{<br />

}<br />

MyFrame mf = new MyFrame("Nom de la fenetre");<br />

JPanel mainPanel = new JPanel();<br />

mainPanel.setLayout(new BorderLayout());//definition du gestionnaire<br />

titre = new JLabel("Saisir puis valider : ", JLabel.CENTER);<br />

text = new JTextField(10);<br />

bouton = new JButton("Quitter");<br />

JPanel saisiePanel = new JPanel();<br />

saisiePanel.add(titre);<br />

saisiePanel.add(text);<br />

mainPanel.add(saisiePanel, BorderLayout.NORTH);<br />

mainPanel.add(bouton, BorderLayout.SOUTH);<br />

mf.getContentPane().add(mainPanel);<br />

mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />

mf.setVisible(true);


2.6 Autres composants<br />

Il existe beaucoup d'autres composants graphiques. Entre autres :<br />

– JComboBox : Composant affichant une liste.<br />

– JRadioButton : Sélection d'une seule valeur parmi plusieurs boutons.<br />

– JCheckBox : Composant pouvant prendre les valeurs vrai/faux.<br />

– JTree : Permet d'afficher une arborescence.<br />

– JProgressBar : Affiche la progression d'une action.<br />

– JTabbedPane : Permet de passer d'un panneau à un autre en<br />

utilisant des onglets.<br />

Tous les composants graphiques héritent de javax.swing.JComponent.<br />

http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JComponent.html


3. Gestion des événements<br />

Une fois les composants graphiques mis en place, il faut pouvoir<br />

récupérer les actions de l'utilisateur.<br />

Composant<br />

graphique<br />

objet événement<br />

objet<br />

événement<br />

objet<br />

événement<br />

Ecouteur 1 Ecouteur 2 Ecouteur N<br />

...<br />

Il faut donc :<br />

– Créer un/des écouteur(s)<br />

– Référencer les écouteurs au niveau des composants


3.1 Créer un écouteur<br />

<strong>Le</strong> rôle de l'écouteur est d'attendre qu'un événement lui soit envoyé.<br />

Il analyse cet événement et execute le code adéquate.<br />

Pour créer un écouteur, il suffit d'implémenter une interface, par<br />

exemple ActionListener :<br />

class MyListener implements ActionListener{<br />

public void actionPerformed(ActionEvent e){<br />

}<br />

}<br />

Lorsqu'un événement est reçu, la méthode actionPerformed est<br />

executée.


3.2 Classes internes<br />

<strong>Le</strong>s classes écouteurs sont spécifiques à l'interface développée.<br />

Elles sont souvent placées à l'intérieur de la classe décrivant<br />

l'interface graphique. Ce sont alors des classes internes.<br />

<strong>Le</strong>s classe internes :<br />

– ont accès aux champs de la classe conteneur<br />

– sont invisibles à l'extérieur de la classe conteneur


3.2 Classes internes (2)<br />

public class MyInterface{<br />

private JTextField text;<br />

private JLabel titre;<br />

private JButton bouton;<br />

public MyInterface(){ ... }<br />

class MyListener implements ActionListener{<br />

public void actionPerformed(ActionEvent e){<br />

if(e.getSource()==text){<br />

System.out.println(text.getText());<br />

}<br />

if(e.getSource()==bouton){<br />

System.out.println("Je quitte!!");<br />

System.exit(0);<br />

}<br />

}<br />

}}


3.3 Lier un composant à un<br />

écouteur<br />

Il nous faut maintenant créer une instance de notre classe écouteur:<br />

public MyInterface{ ...<br />

...}<br />

MyListener listener = new MyListener();<br />

Et indiquer à nos composants qu'ils doivent envoyer les<br />

événements à ce listener :<br />

public MyInterface{ ...<br />

...}<br />

MyListener listener = new MyListener();<br />

bouton.addActionListener(listener);<br />

text.addActionListener(listener);


3.4 Interfaces listener utiles<br />

●<br />

ActionListener : Touche entrée et boutons<br />

● public void actionPerformed(ActionEvent e)<br />

●<br />

KeyListener : Evénements clavier<br />

● public void keyPressed(KeyEvent e)<br />

● public void keyReleased(KeyEvent e)<br />

● public void keyTyped(KeyEvent e)<br />

●<br />

MouseListener : Clics et positionnement de la souris<br />

● public void mouseClicked(MouseEvent e)<br />

● public void mouseEntered(MouseEvent e)<br />

● public void mouseExited(MouseEvent e)<br />

● public void mousePressed(MouseEvent e)<br />

● public void mouseReleased(MouseEvent e)


3.4 Interfaces listener utiles (2)<br />

●<br />

MouseMotionListener : Mouvements de la souris<br />

● public void mouseDragged(MouseEvent e)<br />

● public void mouseMoved(MouseEvent e)<br />

Il existe bien d'autres interfaces écouteur. Toutes héritent de l'interface<br />

EventListener<br />

(http://java.sun.com/j2se/1.5.0/docs/api/java/util/EventListener.html).


Pour aller plus loin...<br />

●<br />

<strong>Le</strong> site officiel de Sun contient énormément d'informations :<br />

documentation de l'API, exemples, tutoriaux...<br />

– http://java.sun.com/j2se/1.5.0/docs/<br />

●<br />

De nombreux sites Internet proposent des exemples de code en<br />

Java, un simple moteur de recherche permet souvent de trouver<br />

des informations pertinentes.<br />

●<br />

Au coeur de Java 2 (Hortsmann & Cornell), CampusPress<br />

●<br />

Java Cookbook (Darwin), O'Reilly

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!