Cours de JAVA Organisation des classes d’entrées/sortie, tutoriel & guide de travaux pratiques JAVA en pdf.
Héritage
L’hÉritage est un mÉcanisme qui permet d’Étendre une classe en lui ajoutant des possibilités ou en redÉ nissant certaines des fonctionnalités existantes.
Concréctement, étant donné une classe A, l’héritage permet de créer une classe B, qui a toutes les caractéristiques de la classe A, plus Éventuellement de nouveaux champs et de nouvelles mÉthodes.
Type et classes : le polymorphisme
Introduisons quelques dÉ nitions 1 :
type un objet a un type et un seul : celui qui lui est donnÉ par son constructeur.
classe un objet peut par contre avoir plusieurs classes : celle correspondant à son type, ainsi que toutes les sur-classes de celle-ci.
Supposons que la classe Etudiant hÉrite de Personne qui hÉrite de Object. Alors :
Personne e= new Etudiant(« toto »);
crÉe un objet de type Etudiant, qui appartient aux classes Etudiant, Personne et Object.
Par contre e est de classe Personne, ce qui est lÉgal car c’est bien une des classes de l’objet.
redÉ nition (overriding) c’est le fait de rÉÉcrire dans une classe B une mÉthode d’une des classes dont B hÉrite. Lorsque cette mÉthode sera appelÉe sur un objet de type B, alors c’est la mÉthode redÉ nie qui sera utilisÉe et non la mÉthode de la classe ancŒtre.
1. L’usage des mots type et classe dans ce sens n’est à notre connaissance pas standard. Cette terminologie provient du livre Design Patterns.
surcharge (overloading) à ne pas confondre avec le prÉcÉdent. c’est le fait d’utiliser le mŒme nom pour des mÉthodes diffÉrentes. Quand les mÉthodes sont dans la mŒme classe, elles sont distinguÉes par leurs arguments. Notez que la surcharge n’a aucun rapport avec l’hÉ-ritage 2.
polymorphisme
super et this
Introduction
En Java, il arrive parfois qu’une variable en « cache » une autre. TrŁs classiquement, consi-dÉrons une classe Etudiant et un de ses constructeurs possibles :
public class Etudiant {
String nom;
public Etudiant(String nom) {
???
}
}
Dans le corps du constructeur, le paramŁtre « nom » cache le champ (ou variable d’instance)
« nom ». Dans 99 % des langages de programmation, le problŁme est rÉsolu en changeant le nom du paramŁtre. C’est là qu’intervient this. « this » signi e « l’objet auquel s’applique la mÉthode », ou, dans le cas d’un constructeur, « l’objet en train d’Œtre construit ». Dans ce cas, l’Écriture « this.nom » n’est pas ambiguº, et dÉsigne bien « le champ nom de l’objet de classe Etudiant que nous construisons ».
Cette fonction, pour Œtre trŁs utilisÉe en Java, n’en est pas moins secondaire : on pourrait fort bien s’en passer. Il est par contre des fois oé l’emploi de this ou de son compŁre super est primordial.
Définitions
this signi e « l’objet auquel s’applique la mÉthode », ou, dans le cas d’un constructeur, « l’objet en train d’Œtre construit » ;
super S’emploie dans le cas d’une classe B qui Étend une classe de base A. Il signi e « l’objet auquel s’applique la mÉthode », ou, dans le cas d’un constructeur, « l’objet en train d’Œtre construit », mais vu comme un objet de classe A.
2. La surcharge en java est un concept simple. En C++, nous verrons qu’elle est bien plus complexe, mais aussi plus puissante
Super et this pour quali er des champs
this : quand un champ d’un objet est cachÉ par une variable locale ou un argument, le mot clef this permet de lever l’ambiguïtÉ et de dÉsigner le champ. Classiquement :
public class Etudiant {
String nom;
public Etudiant(String nom) {
this.nom= nom;
// this.nom : champ nom de this
// nom : argument du constructeur.
}
}
super : si une classe lle dÉ nit un champ dont un homonyme existe dans une classe parente, ce dernier est masquÉ. Soit par exemple le code :
class A {
public int a;
}
class B extends A {
public String a;
…
}
le champ a de type String de B masque le champ int de A. Le mot-clef super permet de faire rÉfÉrence, dans une mÉthode de la classe B, à un objet de classe B en le considÉrant comme un objet de la classe parente, c’est-à-dire A. Ainsi :
class B extends A {
String a;
…
public void afficher() {
System.out.println(a); // affiche le champ String a System.out.println(super.a); // affiche le champ int a
// hÉritÉ de A.
}
}
Notez que cet utilisation de super est trŁs rare. En effet, il est formellement dÉconseillÉ d’accÉder directement aux champs d’une classe. Normalement, on aurait dß Écrire des accesseurs.
Super et this dans les méthodes
this : il est licite d’Écrire
this.appelDeMethode(); mais comme c’est Équivalent à appelDeMethode();
c’est parfaitement inutile.
super : l’idÉe est toujours la mŒme. Supposons que nous ayons :
class Personne {
…
public void afficher() {
// affiche les donnÉes relative à une personne :
// son nom, son prÉnom, son adresse.
…
}
}
class Etudiant extends Personne {
…
public void afficher() {
// affiche les donnÉes relative à un Étudiant :
// d’abord les donnÉes existantes dans la classe Personne,
// puis celles spÉcifiques aux Étudiants.
}
}
Il serait intÉressant de pouvoir utiliser la mÉthode afficher de Personne pour Écrire celle de Etudiant. this comme argument de méthode
Interfaces
Les Interfaces comme spécication
Le mÉcanisme de l’hÉritage en Java est limitÉ à l’hÉritage simple. Une classe a une parente directe et une seule (sauf Object, qui n’en a pas du tout). L’hÉritage a un sens trŁs fort : « B hÉrite de A » signi e « tout B est un A ». Or, il arrive que l’on veuille simplement signi er qu’une classe « sait faire » telle ou telle chose. C’est le sens des interfaces.
Une interface est principalement un ensemble d’en-tŒtes de mÉthodes. Une classe peut im-plÉmenter une ou plusieurs interfaces, c’est à dire fournir le code correspondant aux mÉthodes de l’interface.
Les interfaces comme collections de constantes
Les interfaces peuvent aussi contenir des constantes. Il suf t alors d’implÉmenter l’interface pour pouvoir les utiliser. ConsidÉrons par exemple l’interface suivante :
public interface CodesJours {
int DIMANCHE= 0;
int LUNDI= 1;
int MARDI= 2;
int MERCREDI= 3;
int JEUDI= 4;
int VENDREDI= 5;
int SAMEDI= 6;
}
Notez que ces champs sont en rÉalitÉ static et final, mais qu’il est optionnel de l’Écrire. Toute classe qui implÉmente CodesJours dispose directement des constantes qu’elle dÉ –
nit :
class Calendrier implements CodesJours {
…
initWeekEnd() {
// Notez que SAMEDI est utilisÉ directement jour[SAMEDI].setRepos(true); jour[DIMANCHE].setRepos(true);
}
…
}
Cast
L’opÉration de conversion (casting) couvre en Java deux concepts diffÉrents. Elle se comporte en effet diffÉremment sur les types de base, oé il s’agit d’une vÉritable conversion, et sur les classes, oé c’est plutôt une opÉration syntaxique.
Cast et types de base
Les divers types de base (int, double, etc…) sont plus ou moins compatibles entre eux. On conçoit par exemple qu’il soit logique de pouvoir Écrire un entier dans un double. Java permet d’ailleurs cette opÉration sans autre forme de procŁs :
int i= 1;
double y= i;
Par contre, certaines conversions causent une perte d’information. Écrire un double dans un int, c’est en perdre la partie dÉcimale. De mŒme, Écrire un int dans un short (entier court) peut conduire à une perte de donnÉes.
En Java, les conversions avec perte de donnÉe potentielle sont possibles, mais, contrairement aux conversions sans perte de donnÉes, elles doivent Œtre explicitement marquÉe par l’opÉration de casting.
Un cast permet de convertir une donnÉe d’un type de base en un autre. Il s’Écrit en faisant prÉcÉder la valeur à convertir par le nom du type cible de la conversion, Écrit entre parenthŁses :
double y= 1.3;
int j= (double)y;
Cast et classes
Pour reprendre le vocabulaire de 2.3,
L’identité des objets
Le problŁme de l’identitÉ est simple à premiŁre vue : il s’agit de savoir si deux objets sont
« les mŒmes ». NÉanmoins, les apparences sont trompeuses. Par dÉfaut pour java chaque objet crÉÉ est diffÉrent des autres.
5.1 Comparaison d’objets : equals()
La mÉthode equals est hÉritÉe par toutes les classes. La classe Objet dÉ nit equals comme :
public boolean equals(Objet o)
{
return this == o;
}
C’est donc initialement un Équivalent de ==. Pour les classes qui veulent disposer d’une dÉ ni-tion diffÉrente de l’ÉgalitÉ, on doit redÉ nir equals. C’est ce que fait, par exemple, la classe
String.
Exemple de redÉ nition :
Encapsulation d’un entier
class Entier {
int val;
public Entier(int v) {val= v;}
public boolean equals(Object o) {
// On compare un Entier et un Object.
// Ils peuvent Œtre de type diffÉrent : if (o instanceof Entier)
{
// o est un Entier. Le rÉcupÉrer comme tel
// grâce à un cast :
Entier e= (Entier)o;
return (e.val == val);
}
else
// o n’est pas un Entier. Donc il ne peut Œtre Égal à this return false;
}
// Fonction hashCode. Voir ci-dessous. public int hashCode() {
return val;
}
public int getValeur() {return val;}
public void setValeur(int v) {val= v;}
}
Le hashcode
Si une classe redÉ nit equals, elle doit aussi redÉ nir la mÉthode hashcode :
public int hashcode ()
fonction renvoyant un entier, utilisÉe par les classes comme Hashtable, HashMap et HashSet.
La contrainte est que si deux objets sont Égaux au sens de equals, ils doivent avoir le mŒme hashcode (la rÉciproque n’Étant pas forcÉment vÉri Ée : deux objets peuvent avoir le mŒme code, mais Œtre diffÉrents). Par contre, plus le hashcode diffÉrencie des objets diffÉrents, plus il est ef cace.
Notez qu’une fonction constante remplit les conditions (mais ne fournit pas un « bon » hashcode.
Si hashcode et equals sont en dÉsaccord, les classes telles que HashTable, qui uti-lisent le hashcode, donneront des rÉsultats erronÉs.
Duplication d’un objet : clone()
à rÉdiger
public class Etudiant implements Cloneable {
private String nom;
protected Object Clone() {
try {
Etudiant e = (Etudiant)super.clone();
e.nom = (String)nom.clone();
return e;
} catch (CloneNotSupportedException e) { // Impossible
}
}
}
Important clone() ne peut ni utiliser un constructeur de la classe à cloner, ni appeler new pour construire son rÉsultat.
I Le langage JAVA. Compléments
1 Spécicateurs
1.2 Le mot clé static
1.3 Accès aux champs et méthodes d’une classe
2 Héritage
2.1 Redénition de fonctions
2.2 Implémentation de l’héritage
2.3 Type et classes : le polymorphisme
2.4 Classes abstraites
2.5 super et this
3 Interfaces
3.1 Les Interfaces comme spécication
3.2 Les interfaces comme collections de constantes
4 Cast
4.1 Cast et types de base
4.2 Cast et classes
5 L’identité des objets
5.1 Comparaison d’objets : equals()
5.2 Le hashcode
5.3 Duplication d’un objet : clone()
6 Exceptions
6.1 Introduction
6.2 Terminologie
6.3 Les exceptions en JAVA
6.4 Propagation d’exceptions
6.5 Interception des exceptions en Java
6.6 Dénition d’un type d’exceptions
7 Threads
7.1 Introduction
7.2 Déclaration
7.3 Lancement d’un thread
7.4 Le partage du temps
7.5 Variables partagées
7.6 Contrôle de l’exécution
7.7 Éviter les attentes actives avec wait et notify
7.8 Démons
7.9 Graphismes
II Bibliothèques particulières
1 Les Collections
1.1 Introduction
1.2 Itérateurs
1.3 Organisation des classes
1.4 L’interface Collection
1.5 Listes
1.6 Ensembles
1.7 Dictionnaires (maps)
1.8 Piles (Stack)
1.9 Exemples
2 Entrées/sorties
2.1 La classe File
2.2 Organisation des classes d’entrées/sortie
2.3 Quelques Classes
2.4 Exemples d’utilisation
2.5 Méthodes
2.6 La classe RandomAccessFile
2.7 Sérialisation
2.8 La classe StreamTokenizer
3 Java et les bases de données
3.1 Introduction à JDBC
3.2 Architecture
3.3 Un exemple : postgres
3.4 établir la connexion
3.5 Envoyer une requête
3.6 Commandes préparées
3.7 échappements SQL
3.8 Gestion des transactions
3.9 Capacités de la base de données : DataBaseMetaData
3.10 Exploration des tables
3.11 Extensions du jdbc2.0
4 Java Server Pages et Servlets
4.1 Architecture d’une application web
4.2 Introduction aux jsp
4.3 Introduction aux servlets
4.4 Les javabeans
4.5 Architecture typique d’une application jsp
4.6 Le suivi des sessions
4.7 Création de nouvelles balises pour les jsp
5 Java et XML
5.1 Le langage XML
5.2 Les API Java
5.3 XSL et java
5.4 Quelques outils java utilisant XML
5.5 Appendice : un fragment de la description du langage XML
6 Swing Avancé
6.1 Patterns en swing : l’exemple de JTable
6.2 Le pattern commande en swing : actions et edits
………