C 2 Java
C 2 Java
C 2 Java
Cours Java
1
1437-02-19
2
1437-02-19
3
1437-02-19
4
1437-02-19
5
1437-02-19
6
1437-02-19
7
1437-02-19
8
1437-02-19
9
1437-02-19
10
1437-02-19
11
1437-02-19
Les tableaux
• Un tableau est un ensemble indexé de données d'un même type. L'utilisation d'un
tableau se décompose en trois parties :
• Création du tableau
• Remplissage du tableau
• Lecture du tableau
Création d'un tableau
Un tableau se déclare et s'instancie comme une classe :
• int monTableau[ ] = new int[10];
• int [ ] monTableau = new int[10];
Si [ ] suit le type, toutes les variables déclarées seront des tableaux, alors que si [ ] suit le
nom de la variable, seule celle-ci est un tableau :
Exemple
• int [] premierTableau, deuxiemeTableau;
• float troisiemeTableau[], variable; // variable n'est pas un tableau.
Lorsque la variable est déjà déclarée, nous pouvons lui assigner d'autres
valeurs en utilisant l'opérateur new :
monTableau = new int[] {11,13,17,19,23,29};
12
1437-02-19
System.out.println(«nb = »+ nb ); // nb=11
Remarques
13
1437-02-19
• Pour être utile, un programme doit entrer des données, produire les résultats
après traitement de ces données.
• Ce chapitre discute les entrées et les sorties des données provenant du
clavier et le moniteur.
• Il n'y a pas de déclarations standard dans la langue de Java pour les entrées
et sortie comme pour langage C/C++.
• Toutes les entrées entrés et sortie utilisent des méthodes faisant partie du
même paquet java.io.
14
1437-02-19
• "O" est supposé représenter une donnée (chaîne de données) ordonné en fil
d’attente pour sortir ou pour entrer.
• En général, un programme peut avoir plusieurs flux d'entrés et produit
plusieurs flux de sortie. Pour la plupart des programmes possède trois flux
IO:
• System.in — flux d’entrée
• System.out — flux de sortie
• System.err — flux de sortie pour le message d’erreur.
• Normalement System.in est relié au clavier et les données sont de type
caractères. System.out et System.err les deux sont reliés au moniteur, et
aussi leurs données sont de type de caractères. Le paquet qui gère ces flux
est java.io
java.io.
Exemple
Les données envoie par le clavier à un programme sont de type caractère
incluant les caractères chiffres ‘0' jusqu’a ‘ 9.' Donc il faut convertir ces
caractères en données numériques pour être utilisées dans des opérations
arithmétiques.
import java.io.*;
class Echo{ public static void main (String[] args) throws IOException
{ InputStreamReader inStream = new InputStreamReader( System.in ) ;
BufferedReader stdin = new BufferedReader( inStream );
String inData;
System.out.println("Enter the data:");
inData = stdin.readLine();
System.out.println("You entered:" + inData );
}}
Note :
Utilise la notion d’IOException
IOException qui est nécessaire pour les programmes qui possèdent
un flux d’entrée.
Il informe le compilateur que le programme principal possède une flux d’entrée et qui
peut générer un erreur lors d’une opération de lecture des donnes à partir du clavier
si cela arrive le système informatique sera informé de l'échec et le programme
saura arrêté correctement.
correctement k.afdel cours Java 30
15
1437-02-19
BufferedReader
inData = stdin.readLine();
Le programme lit une ligne de données de type caractère provenant du clavier
en utilisant la méthode readLine qui fait partie de l'objet BufferedReader.
import java.io.*;
class EchoSquare{
public static void main (String[] args) throws IOException
{ BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in));
String inData;
int num, square; // declare two int variables
System.out.println("Enter an integer:");
inData = stdin.readLine();
num = Integer.parseInt
Integer.parseInt( inData ); // convert inData to int
square = num * num ; // compute the square
System.out.println("The square of " + inData + " is " + square);
}
}
16
1437-02-19
import java.io.*;
class StringToDouble{
public static void main (String[] args)
{ final String charData = "3.14159265";
double value;
value = Double.parseDouble( charData ) ;
System.out.println("value: " + value +" twice value: " + 2*value );
}}
Entrées /Sorties
Utilisation de la class Scanner
Etape 1 importez la classe Scanner
import java.util.Scanner;
Etape 2 : saisir les données. Tous les entrées seront effectuées sous forme de chaine par java
Exemple
Scanner sc = new Scanner(System.in);
System.out.println("Veuillez saisir un mot :");
String str = sc.nextLine();
System.out.println("Vous avez saisi : " + str);
Ou saisie de caractère
System.out.println("Saisissez une lettre :");
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
char carac = str.charAt(0);
System.out.println("Vous avez saisi le caractère : " + carac);
Etape 3 : Conversion de la chaine en type de données primitives
Exemple :
Scanner sc = new Scanner(System.in);
int i = sc.nextInt(); System.out.println(" La valeur de i: " + i);
float f=sc.nexFloat(); System.out.println(" La valeur de f: " + f);
double d = sc.nextDouble(); System.out.println(" La valeur de d: " + d);
long l = sc.nextLong(); System.out.println(" La valeur de l: " + l);
byte b = sc.nextByte(); System.out.println(" La valeur de b: " + b);
17
1437-02-19
Programmation Orientée
Objet avec Java
Introduction
• La programmation orientée objet permet de concevoir une application
sous la forme d'un ensemble d'objets reliés entre eux par des relations
• Le programme orienté objet est pensé en terme d'objets abstraits inter
opérant entre eux alors que la programmation traditionnelle pense une
application en termes de fonctionnalités.
• L'une des caractéristiques de cette méthode permet de concevoir de
nouveaux objets à partir d'objets existants.
• Réutiliser les objets dans plusieurs applications. La réutilisation du code
fut un argument déterminant pour venter les avantages des langages à
objets.
• Nous allons découvrir les concepts de l'orienté objet implémentés par
java à savoir :
1. Objet et classe
2. Héritage
3. -Encapsulation (Accessibilité)
4. -Polymorphisme
18
1437-02-19
Objet, Classes
Objet
• Un objet est une structure informatique caractérisée par un état et un
ensemble d'opérations exécutables par cet objet qui caractérise son
comportement.
• Objet = état + comportement (opérations)
• Exemples:
• Objet Une Fenêtre :
– Etat : position, taille, bordure, titre, couleur,...
– Opérations: dessiner, déplacer. agrandir...
• Objet Un Fichier
– Etat : nom, directory, id, protections, propriétaire, contenu..
– Opérations : ouvrir, fermer, détruire,
• On regroupe un ensemble de caractéristiques communes aux objets sous la forme de
structures formelles, appelées classes
– Exemple de représentation graphique d'un objet (Notation UML) :
classe
• Une classe est un modèle de la structure statique (les champs ou attributs) et du
comportement dynamique (les opérations ou méthodes) des objets (instances) associés
à cette classe;
• La classe décrit le domaine de définition d'objets. Chaque objet appartient à une classe.
Les généralités sont contenues dans la classe alors que les particularités dans les objets.
Les objets informatiques sont construits à partir de la classe par un processus appelé
instanciation. De ce fait tout objet est une instance de classe.
19
1437-02-19
• Une classe est définie par les attributs et les opérations (méthodes).
– Attributs : Appelés également champs correspondent aux propriétés de la classe. Ils sont définis
par un nom, un type de données et éventuellement une valeur initiale. Un attribut est une variable
qui stocke des données.
Exemple : considérons la classe Employé caractérisée par les attributs code, nom et nbEmployés (nombre
d'employés)
• Les attributs code et nom sont des caractéristiques de chaque objet Employé
contrairement au champ nbEmployés qui est une caractéristique commune à tous les
objets. On dira que nbEmployés est attribut statique.
statique
• Chaque objet, instance d'une classe, donne des valeurs particulières à tous les
attributs définis dans sa classe sauf les attributs statiques ce qui détermine son état.
• Exemples :
Définition :
• Un attribut statique d'une classe est un attribut qui appartient à la classe et qui est
partagé par tous les objets de cette classe. Un attribut statique est considéré comme
étant une variable globale à tous les objets.
• Les attributs statiques ne sont pas instanciés dans les objets“
• Méthodes :
• Les méthodes permettent de décrire les comportements des objets.
• Représentent des procédures ou des fonctions qui permettent d'exécuter un certain
nombre d'instructions.
• Parmi les méthodes d'une classe existe une méthode particulière, qui porte le même
nom que la classe, qui s'appelle le constructeur. Le rôle du constructeur étant créer les
objets de la classe en les initialisant.
20
1437-02-19
21
1437-02-19
Vers quoi pointe ce handle ? Pour l'instant, il ne pointe donc vers rien.
Modifier l'affectation d'un handle
Employe alpha;
new Employe() ;
• Il n'y a ensuite aucun moyen d'établir un lien entre le handle créé à la première ligne et
l'objet créé à la seconde. Il faut donc effectuer l'affectation en même temps que la
création, de la façon suivante :
• Employe alpha;
• alpha = new Employe () ;
Java nous permet même de condenser ces deux lignes en une seule sous la thème :
22
1437-02-19
Exemple
23
1437-02-19
Classe TestEmploye :
class TestEmploye{
public static void main(String[] args){
new Employe(); // Crée un objet anonyme
Employe e2 ; //Crée un handle,pour le moment, in pointe vers null
e2=new Employe
Employe();(); //Crée un objet Employe puis affecte son adresse au handle e2
Employe e3=new Employe(); //Crée le handle e3, crée un objet et affecter l'objet au handle e3
e2.nom:"Jamil"; // définit la valeur I'attribut nom de I'objet e2
e2.afficheCode(); // on fait appel à la méthode afficheCode() de I'objet e2
e2.afficheNom();// on fait appel à la méthode afficheNom() de I'objet e2
e3.afficheCode();// on fait appel à la méthode afficheCode() de I'objet e3
System.out.println("Nombre d'employés en utilisant I'objet e2--" + e2.nbEmployes);
System.out.println( "Nombre d'employés en utilisant I'objet e3 :"+ e3.nbEmployes ) ;
System.out.println("Nombre d'employés en utilisant la classe Employe" +
e2.nbEmployes);
}}
k.afdel cours Java 47
24
1437-02-19
Héritage
Le développement d'une application Java peut se décomposer en deux
phases:
• La 1ière phase de conception, consiste à représenter l'univers du problème
à l'aide d'un ensemble de classes ( digramme des classes UML).
• La 2ième implémentation, consiste à construire ces classes.
Dans Java, tous les éléments que manipule un programme sont des objets objets, à
l'exception des primitives. Cependant, les primitives peuvent être traitées
comme des objets grâce aux enveloppeurs.
Si l'on considère la hiérarchie suivante :
25
1437-02-19
L’héritage
• Les classes Chien, Chat et Canari sont des sous classes de la
classe Animal ; on dira que la classe Chien hérite de la classe
Animal.
• De même, les classes Teckel, Labrador et Caniche, héritent de la
classe Chien et donc par transitivité, héritent également toutes las
caractéristiques de la classe Animal.
• Dans java la super classe d’une hiérarchie de classes est une classe
prédéfinie nommée Object.
Autrement dit, si une classe n’hérite pas d’une autre, elle hérite
automatiquement de la classe Object.
• la classe Animal
Animal class Animal {
// Attributs : // Attributs
vivant : boolean boolean vivant; int âge;
age : int // Constructeur
Animal (int a) { âge = a; vivant = true;}
//Constructeur : //Méthodes
Animal(int a) void vieillit() {++âge;}
//Méthodes : void meurt() {vivant = false;}
crie() void crie() {}
vieillit() }
Meurt()
Ce qui signifie qu'un animal possède un état (vivant, qui peut être vrai ou faux et âge,
qui est une valeur numérique) et sait faire plusieurs choses ( crie(), vieillit() et meurt(),
qui sont des méthodes).
• La méthode vieillit() permet d’incrémenter d’une unité l’attribut âge.
• La méthode meurt() initialise l’attribut vivant à false.
• La méthode crie() ne fait rien, mais sa présence indique qu'un Animal crie(), mais
pour le moment, on ne connaît pas la nature de son crie.
La création d'un Animal se ferait à l'aide de l'instruction suivante :
Animal nouvel Animal = new Animal (3 (3);
26
1437-02-19
• Pour éviter de réécrire, dans le constructeur de la classe Canari, les mêmes instructions du
constructeur de la classe Animal, on peut faire appel au constructeur de la classe parente en
utilisant l'identificateur super
super.
Remarque : La seule chose, dans notre modèle, qui distingue un Canari d'un autre
Animal est son cri.
Pour mettre en œuvre cette différence, nous devons utiliser une technique appelée
method overriding, en anglais, que l'on peut traduire par redéfinition de méthode.
La redéfinition des méthodes
• La classe Canari hérite de la classe Animal la méthode crie().
• Or cette méthode ne convient pas à la classe Canari car on connaît
maintenant la nature du crie d’un canari.
• Avec les concepts de l’héritage, nous avons la possibilité de redéfinir cette
méthode pour en créer une nouvelle version.
La classe Canari s’écrit à nouveau de la manière suivante :
27
1437-02-19
Le test de la classe
class Animaux {
public static void main(String[] args) {
Canari titi = new Canari(3);
titi.vieillit();
titi.crie(); }
}
• Appel à la méthode vieillit() de l’objet titi. Cette méthode n’a pas été définie dans la
classe Canari, mais elle a été hérité de la classe Animal.
Animal Cet appel permet
d’incrémenter l’attribut âge de l’objet titi (âge=4).
• On peut constater que la méthode vieillit() est un cas particulier de la méthode vieillit(int a) avec a=l. la méthode vieillit()
peut donc s’écrire d’une manière plus optimisée de la manière
k.afdel courssuivante
Java : 56
void vieillit() { vieillit(1); }
28
1437-02-19
29
1437-02-19
// Deuxième constructeur
Animal (int a) { âge = a; vivant = true; Animal al = new Animal();
System.out .println ("Un animal de ,,+a+,,an (s) vient d'être créé");} // âge=l Ou en indiquant l’age :
void vieillit(){++âge; Animal a2 = new Animal(4);
System.out.println("C1 est l'anniversaire de cet animal."); // âge=4
System.out.println("Il a maintenant " + âge + " an(s) ;}
30
1437-02-19
• De la même manière que les deux méthodes vieillit() et vieillit(int a), le premier
constructeur est un cas particulier du deuxième.
• Pour éviter de réécrire deux fois les mêmes instructions dans les deux constructeur, on
peut faire appel au deuxième constructeur à l’intérieur du premier.
•
• Toutefois, l’appel d’un constructeur à l’intérieur d’un autre ne peut pas se faire en
écrivant son nom mais en utilisant le mot this suivi des arguments du constructeur
appelé entre parenthèse.
• Le premier constructeur peut s’écrire d’une manière plus optimisée comme suit:
// Premiser Constructeur
Animal () {
this(l) ; // au lieu de Animal(1)
}
// Deuxième Constructeur
Animal (int a) {
âge = a; vivant = true;
System.out .println ("Un animal de" +a+" an (s) vient d'être créé");
}
Les constructeurs par défaut
• En l’absence du constructeur dans une classe, java fournit automatiquement un
constructeur par défaut. Le constructeur par défaut est le suivant :
k.afdel cours Java 61
NomDeLaClasse ( ) { }
31
1437-02-19
Encapsulation
• Encapsulation en Java est un concept qui renforce la protection des variables,
des méthodes de l'extérieur de la classe;
• Encapsulation est un concept pour mieux gérer ce fragment de code pour qui
il est moins d'impact ou aucun impact sur d'autres parties du programme;
• L'importance de l'encapsulation se manifeste dans un environnement qui est
sujette à changement fréquents comme c’est la cas dans le domaine de
développement qui confronté à des exigences de logiciels changent tous les
jours.
• L'idée derrière le concept de l'encapsulation est que si une fonctionnalité qui
est bien encapsulé dans le code c-à-d maintenu dans un seul endroit et non
dispersés dans tous le code- est facile à changer et à gérer.
• Langage Java fournit de nombreux mode pour encapsuler les membres d'une
classe.
– Mode private pour encapsuler complètement un membre que ce soit un attribut ou
une méthode en Java
– Mode protected ou public pour obtenir un degré moindre d'encapsulation
Exemple
• Supposons que nous ayons une classe PRET avec un constructeur et que
dans les différentes classes vous avez créés des instances de la class
PRET en utilisant le constructeur.
• Les exigences logicielles ont maintenant changés et vous devez inclure
l'âge de l'emprunteur.
• Puisque ce code n'est pas bien encapsulé-à-dire ne se limite pas à un seul
endroit-vous devez changer partout où vous appelez ce constructeur.
32
1437-02-19
Solution
• Dans notre exemple nous allons encapsuler la logique de création de l'objet de la
classe PRET dans la méthode CreatePRET () autrement dit la création de l'objet va
s'effectuer dans une seul endroit en appelant le constructeur à l'intérieur de la
méthode CreatPret().
• Le client peut appeler cette méthode qui va créer l'objet PRET. Maintenant s'il ya
modification comme le cas d'ajouter l'âge du Prêteur dans ca cas il suffit de modifier
uniquement le constructeur dans la méthode CreatePRET() et non pas aller chercher
la où se trouve le constructeur pour le modifier.
class PRET //no argument consustructor omitted here
{
private int periode ; //private variables
// create PRET can encapsulate PRET -
examples of encapsulation
Object creation logic
private String prêt_type;
public PRET CreatePRET(){
private String preteur;
private String salaire;
//processing based on loan type and
then returning loan object
//public constructor can break
/*PRÊT pret_obj= new PRÊT(p,ptype,
encapsulation instead use factory method
prteur,sal);*/
private PRET(int periode, String pret_typ
e, String preteur, String salaire){
PRÊT pret_obj= new PRÊT(p,ptype,
this. periode = periode;
prteur,sal, ag);
this. pret_type = pret_type;
this. preteur = preteur;
return pret_obj;
this. salaire = salaire;
} }
}
k.afdel cours Java 66
33
1437-02-19
Advantage de l’Encapsulation
1. code encapsulé est plus souple et plus facile à changer avec les nouvelles
exigences logicielle.
2. Encapsulation en Java facilite le test unitaire
3. Encapsulation en Java vous permet de contrôler qui peut accéder à quoi.
4. Encapsulation contribue également à écrire classe immuable en Java qui
sont un bon choix dans un environnement multi-threading.
5. Encapsulation réduire le couplage de modules et de renforcer la cohésion
à l'intérieur d'un module parce que tout morceau de code est encapsulé
dans un seul endroit.
6. Encapsulation vous permet de modifier une partie du code sans affecter
autre partie du code.
Niveaux d'encapsulation
Les 4 niveaux d'encapsulation de Java sont par ordre de visibilité croissante :
• un membre privé (private) n'est visible que dans les instances
• directes de la classe où il est déclaré.
• un membre sans modifieur est visible uniquement dans les instances
directes de la classe où il est déclaré et dans celles des classes du
même paquetage.
• un membre protégé (protected) n'est visible que dans les instances,
directes ou non, de la classe où il est déclaré (et donc aussi dans les
instances des sous-classes) et dans les instances des classes du
même paquetage.
• un membre public (public) est visible par n'importe quel objet.
34
1437-02-19
•Les variables membres déclarées private sont bien encapsulés vous ne pouvez
modifier ou accéder à ces variable directement qu'à l'intérieur de cette classe.
• si vous souhaitez autoriser les classes extérieur à accéder à ces variables il faut
créer les méthodes d’accès (accesseur) getter et setter
35
1437-02-19
private visible
visible visible
Remarque
Les classes qui ne sont pas déclarées dans un paquetage font toutes partie du même
paquetage « anonyme ».
36
1437-02-19
Remarques :
Comme dans le cas des variables, les méthodes static peuvent être référencées
à l'aide du nom de la classe ou du nom de l'instance.
Il est important de noter que les méthodes static ne peuvent en aucun cas faire
référence aux méthodes ou aux variables non static de la classe.
Elles ne peuvent non plus faire référence à une instance. (La référence this ne
peut pas être employée dans une méthode static.)
• Les méthodes static ne peuventk.afdel
pas non
coursplus
Java être redéfinies dans les classes
74
dérivées.
37
1437-02-19
2- final
• Java ne dispose pas de constantes. Ce n'est pas une limitation, car Java
dispose d'un mécanisme beaucoup plus puissant qui permet non seulement
d'utiliser une forme de constantes, mais également d'appliquer ce concept à
d'autres éléments comme les méthodes ou les classes.
Les variables final
• Une variable déclarée final ne peut plus voir sa valeur modifiée. Elle remplit
alors le rôle d'une constante dans d'autres langages.
• Une variable final est le plus souvent utilisée pour encoder des valeurs
constantes.
Par exemple: final float pi = 3.14;
Les variables final non initialisées
• Il existe en fait deux types de constantes dans un programme : celles dont
la valeur est connue avant l'exécution du programme, et celles dont la
valeur n'est connue qu'au moment de l'exécution.
• Une variable final non initialisée est simplement déclarée de la façon
suivante : final int a;
Evidemment, cette variable ne pourra pas être utilisée avant d'être initialisée.
Une fois initialisée au moment de l’exécution, sa valeur ne peut plus être
modifiée.
k.afdel cours Java 75
38
1437-02-19
3- abstract
Le mot clé abstract peut être employé pour qualifier une classe ou une méthode.
Une méthode déclarée abstract ne peut pas être exécutée. En fait, elle n'a pas d'existence réelle. Sa
déclaration indique simplement que les classes dérivées doivent la redéfinir.
Dans l'exemple de la classe Animal, la méthode crie() aurait pu être déclarée abstract :
abstract class Animal { abstract void crieO;
}
• Nous savons simplement qu'un animal a un cri mais on ne peut pas définir le cri de l’animal.
• C'est exactement la signification du mot clé abstract. La méthode ainsi définie indique qu'une
sous-classe devra définir la méthode de façon concrète.
Les interfaces
• Une classe peut contenir des méthodes abstract et des méthodes non abstract.
• Il existe une catégorie particulière de classes qui ne contient que des méthodes
abstract : interfaces.
• Les interfaces sont toujours abstract, sans qu'il soit nécessaire de l'indiquer
explicitement.
• De la même façon, il n'est pas nécessaire de déclarer leurs méthodes abstract.
• Les interfaces obéissent par ailleurs à certaines règles supplémentaires.
– Elles ne peuvent contenir que des variables static et final (des constantes).
– Elles peuvent être étendues comme les autres classes, avec une différence
majeure : une interface peut dériver de plusieurs autres interfaces.
– En revanche, une classe dérive toujours d'une autre classe et peut dériver, en
plus, d'une ou de plusieurs interfaces. Une classe est définie de la manière
suivante :
interface nomlnterface extends interfl, interf2, interface3,.... { //déclaration des constantes de l'interface
elles sont //implicitement de type static final MAX=3 ;
MIN=1 ;
// déclaration des méthodes abstraites. Elles sont implicitement //de type public abstract void afficher()
; int getNom() ;}
• Une classe peut hériter d’une seule classe et de plusieurs interfaces. La
syntaxe est la suivantes :
class maClasse extends autreClasse implements
interfl, interf 2, interf 3,... { }
k.afdel cours Java 78
39
1437-02-19
4- transient :
• Le mot clé transient s'applique aux variables d'instances (primitives et objets). Il
indique que la variable correspondante est transitoire et que sa valeur ne doit pas
être conservée lors des opérations de sérialisation.
• La sérialisation sera étudiée dans un prochain chapitre. Sachez simplement pour
l'instant que cette opération permet d'enregistrer sur disque un objet Java afin de le
conserver pour une session ultérieure, ou de l'envoyer à travers un réseau.
• Lors de la sérialisation, tous les champs de l'objet sont sauvegardés à l'exception de
ceux déclarés transient.
5- synchronized
• Le mot clé synchronized modifie également les conditions d'accès aux classes et
aux objets. Il concerne uniquement les programmes utilisant plusieurs threads, c'est-
à-dire plusieurs processus se déroulant simultanément.
• Java permet de réaliser facilement ce genre de programme. Par exemple, vous
pouvez concevoir un programme dans lequel des objets d'un tableau sont modifiés
fréquemment.
• De temps en temps, le tableau doit être trié pour améliorer les conditions d'accès.
• Cependant, les objets ne doivent pas être modifiés pendant que le tri s'exécute. Il
faut donc s'assurer que la méthode permettant de modifier un élément du tableau ne
pourra pas accéder à celui-ci lorsque le tri est actif.
Polymorphisme
40
1437-02-19
41
1437-02-19
Instanciation et héritage
Pour qu'un objet puisse être considéré comme une instance de la classe Pomme ou une
instance de la classe Fruit, Il faut donc que, lors de l'initialisation, un objet de chaque
classe soit créé.
Exemple:
abstract class Fruit{ class Pomme extends Fruit{
int poids; Pomme(int p){ this.poids=p;
Fruit ( ) { System.out.println("création d'une pomme de "+
System.out.println("Création d'un fruit"); poids+" grammes ");}
} void affiche(){
void affiche(){ System.out.println("C'est une pomme");}
System.out.println("c’ est un fruit"); void affichePoids(){
}} System.out.println("le poids de la pomme est
:"+poids + " grammes");}}
//**********************************************************
class Orange extends Fruit{
Orange(int p){ poids=p; //************************************************
System.out.println("création d'une orange de "+ class Polymorphisme{
poids+" grammes"); } public static void main(String[] args){
void affiche(){ Pomme p=new Pomme(72);
System.out.println("C'est une Orange");} Orange o=new Orange(80);
void affichePoids(){ }
System.out.println("le poids de l'orange est:"+poids+ }
"grammes");}}
//*******************************************************
42
1437-02-19
Remarque
La classe Fruit est abstract car on ne souhaite pas qu'il soit possible de créer un fruit
sans indiquer de quel type de fruit il s'agit.
class Polymorphisme2
{ public static void main(String[] args){
Fruit f1; //Création d'un handle fl de type Fruit
Fruit f2; //Création d'un handle f2 de type Fruit
f1=new Pomme(60); //sur-casting implicit
f2=(Fruit)new Orange (40); // surcasting explicit } }
• Un objet de type Pomme peut être affecté à un handle de type fruit sans aucun
problème :
• f1=new Pomme(60);
• Dans ce cas l’objet Pomme est converti automatiquement en Fruit. On dit que l’objet
Pomme est sur- casté en Fruit.
• Dans java, le sur-casting peut se faire implicitement.
• La casting explicit se fait en précisant la classe vers laquelle on convertit l’objet entre
parenthèse. Exemple : f2=(Fruit)new Orange(40);
43
1437-02-19
Le « late binding »
Early binding, (liaison précoce) : Le lien entre l'appel et la méthode est alors établi au
moment de la compilation Java utilise cette technique pour les appels de méthodes
déclarées final. Elle a l'avantage de permettre certaines optimisations. En revanche,
pour les méthodes qui ne sont pas final, Java utilise la technique du late binding
(liaison tardive). Le lien entre l'appel et la méthode est alors établi au moment de l’
exécution
Exemple :
La méthode affiche() possède 3 versions définies dans les classes Fruit, Pomme et
Orange.
Grâce au late binding, java est capable de déterminer, au moment de l’exécution, quelle
version de méthode qui sera appelée ce que nous pouvons vérifier par le programme
suivant :
class Polymorphisme4{ L’exécution de ce programme donne :
public static void main(String[] args) Création d'un fruit
{ Fruit f1; creation d'une pomme de 60 grammes
Fruit f2;
f1=new Pomme(60); Creation d'un fruit
f2=new Orange (40); creation d'une orange de 40 grammes
f1.affiche();
f2.affiche();} } C'est une pomme
C'est une Orange
44
1437-02-19
Tableaux Objet
Déclaration : LesFruits
• Exemple : Tableau d’objets Fruit
• Fruit[] lesFruits;
Création du tableau.
• lesFruits = new Fruit[5];
Création des objets:
• lesFruits[0]=new Pomme(60);
• lesFruits[l]=new Orange(lOO);
• lesFruits[2]=new Pomme(55);
Manipulation des objets:
• for(int i=0;i<lesFruits.length;i++) lesFruits[i].affiche();
Remarque :
• Un tableau d’objets est un tableau de handles
•
class Polymorphisme5{
public static void main(String[] args ) {
// Tableau de fruits
Fruit[] lesFruits;
lesFruits=new Fruit[3];
lesFruits[0]=new Pomme(60);
lesFruits[1]=new Orange(70);
lesFruits[2]=new Pomme(55);
for(int i=0;i<lesFruits.length;i++) lesFruits[i].affiche();}}
k.afdel cours Java 90
45
1437-02-19
Vecteur
La classe Verctor du package java.util est une structure qui représente un tableau dynamique
d’objets de type Object.
Déclaration :
• Vector lesFruits;
Création du vecteur
• lesFruits= new Vector();
Affectation des objets au vecteur
• lesFruits.addElement(newPomme(60));
• lesFruits.addElement(newOrange(100));
• lesFruits.addElement(newPomme(55));
Manipulation des objets:
• for(int i=0;i<lesFruits.size();i++) ((Fruit)lesFruits.elementAt(i)).affiche();
Autes méthodes de la classe Vector: removeElement(int index)
Exemple
import java.util.*; // pour la classe Vector class
Polymorphisme6{
public static void main(String[] args){
// Vecteur de fruits
Vector lesFruits=new Vector();
for(int i=0;i<lesFruits.size();i++)
//lesFruits.elementAt(i).affiche() // Sous-Casting Obligatoire
k.afdel cours Java
((Fruit)lesFruits.elementAt(i)).affiche();} 91
Les entrées/sorties
• Pour effectuer une entrée ou une sortie de
données en Java il faut
– Ouverture d’un moyen de communication;
– Écriture ou lecture des données;
– Fermeture du moyen de communication
– En java, les moyens de communication sont
représentés par des objets particulier les flux
ou stream
46
1437-02-19
47
1437-02-19
Serialisation
class Carrosserie implements Serializable {
String valeur;
Carrosserie (String s){
valeur =s;
}
String getValeur()
{return valeur; }
}
class Moteur implements Serializable {
String valeur;
Moteur (String s)
{ valeur=s; }
String getValeur()
{return valeur; }
k.afdel cours Java 95
}
48
1437-02-19
Deserialisation
import java.io.*;
public class deserialisation {
public static void main (String [] args) throws IOException,
ClassNotFoundException {
FileInputStream f= new FileInputStream ("garage");
ObjectInputStream o=new ObjectInputStream(f);
voiture voiture1
voiture1=(voiture)o.readObject();
voiture voiture2
voiture2=(voiture)o.readObject();
o.close();
System.out.println("Carrosserie : "+ voiture1.getCarrosserie());
System.out.println("Moteur : "+ voiture1.getMoteur());
System.out.println("Carburant : "+ voiture1.getCarburant());
System.out.println("Carrosserie : "+ voiture2.getCarrosserie());
System.out.println("Moteur : "+ voiture2.getMoteur());
System.out.println("Carburant : "+ voiture2.getCarburant());}}
Accès Directe
La classe RandomAccessFile
• Les entrées /sortie vue jusqu’à présent
sont de type séquentiel
• Inconvénient avec ce type d’accès
– Il faut beaucoup de temps pour accéder à des
données depuis le début;
• Les fichier à accès direct n’utilise pas des
stream il utilise la classe
RandomAccessFile qui dérive de la classe
Object
k.afdel cours Java 98
49
1437-02-19
import java.io.*;
public class AcessDirect{
public static void main (String[] args) throws IOException{
RandomAccessFile original, copie;
File f1=new File("originale.jpg");
File f2=new File("copîe.jpg");
• Nous allons montrer les grandes lignes de passage entre un modèle UML
et Java dans ses cas les plus courants.
CAS D'ASSOCIATION 1 - 1
CAS D'ASSOCIATION 1 – n
50
1437-02-19
NAVIGABILITÉ RESTREINTE
Implémentation en Java
public class A {
public abstract class A {
public A() {
...
...
}
}
….
}
public interface A {
...
Exemple }
public class A {
public String a1; public class A {
package String a2; ...
protected String a3; }
private String a4;
public void op1() { public class B extends A {
... ...
} }
public void op2() { public interface Ia {
... ...
} }
}
public class A implements Ia {
...
}
51
1437-02-19
public class A {
private B rb; public class B {
public void addB( B b ) { ... // La classe B ne connaît pas l'existence de la classe A
if( b != null ) { this.rb=b; } }
}
} Association bidirectionnelle
public class A {
private ArrayList <B> rb;
public A() { rb = new public class B {
ArrayList<B>(); } private A ra;
public ArrayList <B> getArray() public B() {}
{return(rb);} public A getA() { return (ra); }
public void remove(B public void setA(A a){ this.ra=a; }
b){rb.remove(b);} public void addA(A a){
public void addB(B b){ if( a != null ) {
if( !rb.contains(b) ){ if( !a.getArray().contains(this)) {
if (b.getA()!=null) if (ra != null) ra.remove(this);
b.getA().remove(b); this.setA(a);
b.setA(this); k.afdel cours Javara.getArray().add(this); } } 104
rb.add(b); } }} }
}
52