Cours Java Smi 2324
Cours Java Smi 2324
Cours Java Smi 2324
1
Chapitre 2 : Vocabulaires et notions de base
2
I. Opérateurs
1. Opérateurs logiques
&& : Ne vérifie le 2eme opérande qu’après que le contexte nécessite cette vérification.
& : contraire de &&.
Idem pour | et ||.
Exemple:
i=5 ;
++i ; //i a comme valeur 6.
i=6 ;
n= ++i-6 ; //n vaut 1
n=i++ -6 ;// n vaut 0 et vaut 7
i++ ;
++i ;
3. Opérateurs de cast :
Exemple :
int n=1000 ;
byte b ;
b=(byte)n ; //ok
Les valeurs de b et n sont différentes parce que cette opérateur n’a pris que les 8 bits les moins
significatifs de n car n=1000 n’est pas représentable dans le type byte.
3
1. Instruction if
Syntaxe :
if (condition)
Bloc_1 d’instructions
[ else
Bloc_2 d’instructions]
2. Instruction switch
Syntaxe :
switch (expression)
{ case constante_1 : [ suite_d’instructions_1 ]
case constante_2 : [ suite_d’instructions_2 ]
..............
case constante_n : [ suite_d’instructions_n ]
[ default: suite_d’instructions ]
}
Syntaxe:
do instructions
while (condition) ;
4. Instruction while
Syntaxe:
while (condition)
instructions
5. nstruction for
Syntaxe :
for ( [initialisation] ; [condition] ; [incrémentations])
instruction
4
Exemple :
public class Exemple{
Scanner s=new Scanner(System.in);
public static void main (String args[]){
double x;
do
{ System.out.print ("donnez un flottant > 0 (0 pour finir):
") ;
x = s.nextDouble() ;
if (x < 0) {
System.out.println (" ce nombre n’est pas > 0") ;
continue ;
}
System.out.println (" Sa racine est " + Math.sqrt(x)) ;
}
while (x != 0) ;
}
}
5
Chapitre 3 : Classes et objets
6
I. Introduction
La notion de classe généralise celle de type, une classe se caractérise par des données ( ou
champs) et des méthodes .
Un objet généralise la notion de variable. A partir d’une classe, on peut créer, on dit aussi
instancier, un ou plusieurs objets, chaque objet comporte ses propres données.
Exemple :
1. Constructeurs
Dans l’exemple précédent pour attribuer des valeurs aux champs d’un objet de type Point, il
est nécessaire d’utiliser la méthode initialise. La notion de constructeur nous permet
d’automatiser l’opération d’initialisation d’un objet. Cette initialisation ne sera pas limitée à
l’attribution de valeurs initiales mais il pourra s’agir de la mise en place de n’importe quel
traitement utile au bon fonctionnement de l’objet.
7
Reste à ajouter qu’un constructeur n’est rien d’autre qu’une méthode, sans valeur de retour,
portant le même nom que la classe. Il peut disposer d’un nombre quelconque d’arguments.
8
Une classe n’ayant aucun mode d’accès reste accessible à toutes les classes du même
paquetage (même fichier source).
Constructeurs
Méthodes d’accès getXxxx
Méthodes d’altération setXxxx
En Java si des champs doivent exister dans chacune des instances d’une classe, on peut les
définir comme un seul exemplaire pour tous les objets de cette même classe. Ces champs
s’appellent des champs de classe ou champs statistiques en les déclarants avec le mot clé
static.
Exemple 1:
class A {
int n;
float x ;
}
A a= new A() ;
A aa=new A() ;
a.n aa.n
a a.x aa.x
aa
Exemple 2:
class B{
static int n ;
float x ;
}
B b1= new B ( ) ;
B b2= new B ( ) ;
9
B.n B.n
b1.n b2.n
b1.x b2.x
b1 b2
Exercice 1 :
Ecrire une classe objet qui permet d’afficher le nombre des objets instanciés.
class Objet {
public Objet ( ) {
n++ ;
System.out .println(‘’Le nombre des objets instanciés est :
‘’+n) ;
}
private static int n=0 ;
}
public class Main{
public static void main(String args[]) {
Objet a,b,c ;
a = new Objet ( ) ;
………
}
En Java les méthodes de classe sont des méthodes indépendantes des objets qu’on peut
instancier à partir de cette classe. Les méthodes de classe servent à :
Agir sur des champs de classe.
Permettre aux objets d’une classe de disposer des informations collectives
En java, les méthodes de classes semblent pratiques pour permettre à différents objets d’une
classe d’avoir des informations collectives. Les méthodes de classes aussi peuvent fournir des
services n’ayant de sens qu’au sein de la classe elle-même.
10
Remarque :
Les constructeurs ne sont guère concernés par l’initialisation des champs statique d’une
classe.
3. Surdéfinition de méthodes.
Exemple : a+b
Exemple 1:
‘’Ali’’,
This(pNom,‘’Ali‘’,0) ;
This(‘’Amrabet’’,‘’Soufiane ‘’,0) ;
Exemple 2:
11
{
System.out.print ("Salut,");
return (a + b);
}
12
Chapitre 4 : Tableaux
13
I. Tableaux à un seul indice
1. Introduction
Un tableau est un objet conteneur qui contient un nombre fixe de valeurs d'un même type. La
longueur d'un tableau est établie lorsque le tableau est créé. Après création, sa longueur est
fixée.
1
Image prise du site d’Oracle
Chaque composante d'un tableau est appelée un élément, et chaque élément est accessible par son
index numérique. Comme le montre l'illustration précédente, la numérotation commence par 0. Le
9ème élément, par exemple, serait donc accessible à l'index 8.
14
T[4] = 500;
T[5] = 600;
T[6] = 700;
T[7] = 800;
T[8] = 900;
T[9] = 1000;
Dans une situation de programmation réelle, on utilise l'une des instructions en boucle pour
parcourir chaque élément du tableau, plutôt que d'écrire chaque ligne individuellement
comme dans l'exemple précédent.
1. Déclaration
type t [ ] [ ] ;
type [ ] [ ] t;
15
Les déclarations ci-dessus indiquent que t est une référence à un tableau, dans lequel chaque
composante est elle-même une référence à un tableau.
Pour créer un tableau des entiers par exemple :
Le tableau t comporte deux éléments dont chacun est une référence à un autre tableau.
(Voir le schéma suivant)
16
2. Initialisation :
Comme les tableaux à une seule dimension, les tableaux à plusieurs dimensions peuvent être
initialisés par leurs initialiseurs.
Exemple :
float [ ] [ ] t= {{1,2},{3,4}} ;
Pour parcourir un tableau à plusieurs dimensions avec for..each, il faut utiliser la syntaxe
suivante :
for(type [] n :t)
for(type m:n)
17
Chapitre 4 : Héritage
18
I. Introduction
Comme on a vu dans le premier chapitre, l’héritage est à l’origine des possibilités de
réutilisation de programmes en Java. L’héritage nous aide à définir des nouvelles classes dites
classes filles ou dérivées à partir de classes de base nommées classes mères, parentes ou
super-classes.
Les classes filles héritent les fonctionnalités des classes parentes qu’elles pourront modifier
ou compléter à volonté. On peut dériver d’une classe donnée autant de classes filles qu’on le
désire, une classe fille ou descendante pourra à son tour servir de classe de base.
1. Préliminaires
Nous allons mettre en place la notion d’héritage en Java à l’aide d’un exemple consistant à
écrire une classe nommée Point3D qui dérive de la classe Point :
19
Le mot clé super consiste à appeler le constructeur de la classe parente. Ce mot clé appelant
le constructeur de la classe mère doit toujours représenter la première instruction du corps du
constructeur de la classe fille et par conséquence on ne peut pas avoir en même temps les
deux mots clés this et super.
Remarques :
Un objet d’une classe dérivée peut accéder aux méthodes publiques de sa classe
parente.
Pour compiler une classe fille, sa classe de base doit appartenir au même fichier ou
doit être déjà compilée.
Comme nous l’avons déjà signalé pour les classes simples, la création d’un objet fait
intervenir plusieurs phases :
Allocation mémoire,
Initialisation par défaut des champs,
Initialisation explicite des champs,
Exécution des instructions du constructeur.
La généralisation à un objet d’une classe dérivée est assez intuitive. Soit :
20
Exécution du corps du constructeur de B.
3.1 Surdéfinition
Nous avons déjà vu la surdéfinition des méthodes dans une même classe, cette notion peut
être généralisée dans le cas des classes dérivées. En effet une classe fille peut définir une
méthode d’une classe parente et par la suite ces méthodes surdéfinies ne seront utilisables que
par la classe dérivée ou ses descendantes.
Exemple :
class M{
Public void m(int n)
{…..}
…………….
}
class F extends M{
public void m(double d){…..}
M a;
F b;
int n;
double d;
…….
a.m(n); //appel de m de M
b.f(d) ; //f de F
b.f(n) ;
}
La redefinition des méthodes consiste à fournir une nouvelle définition d’une méthode d’une
classe parente dans une classe fille et ce tout en gardant le même type de retour, le même nom
et les mêmes types des arguments.
21
private float x,y ;
public Point(float x, float y){
this.x=x;
this.y=y;
}
public void affiche(){
System.out.println(“Coordonnées sont : ‘’+x+’’ , ‘’+y) ;
}
}
public class Point3D extends Point {
private float z;
public Point3D(float x, float y, float z) {
super(x,y);
this.z=z;
}
public void affiche(){
affiche();
System.out.println(‘’,’’+ this.z);
}
}
Remarque:
La redéfinition d’une méthode n’entraine pas nécessairement l’appel de cette dernière par
super.
5. Polymorphisme
5.1 Introduction
Exemple :
23
public void parler(){
System.out.println(‘’Je parle en anglais’’) ;
}
p=a ;
p.parler()//affiche je parle en arabe
Remarque :
Nous donne :
1 x
(Point) p
2 y
3 x
(Point) p
4 y
5 z
24
Prenons maintenant les deux instructions suivantes :
Dans la première instruction la méthode affiche appelée est celle définie dans Point tandis
que la deuxième instruction appelle la méthode affiche redéfinie dans la classe Point3D. Le
choix de la méthode affiche est basé sur le principe de ligature dynamique ou liaison
dynamique.
Le polymorphisme permet d’obtenir un comportement adapté à chaque type effectif d’objet
(le type de l’objet lors de l’exécution), donc le polymorphisme en Java consiste à assurer deux
principes : La compatibilité par affectation et la ligature dynamique.
Exercice :
Ecrire un programme Java basé sur le polymorphisme pour créer un tableau d’objets de type
Point et Point3D (Voir la séance de cours).
25
9. c.m(n) ; //appel m(float) de C2
}
}
Dans l’instruction 6, la méthode m appelée est celle de C1 ce qui est naturel car un entier est
un float, l’appel dans l’instruction 7 concerne la méthode m(int) de la classe C2 ce qui est
trivial.
Dans l’instruction 9, pour choisir la méthode à appeler le principe de la ligature dynamique
est mis en place. En effet, l’objet c lors de la compilation contient une référence à un objet de
type C1 ce qui entraine la détermination de la méthode m(float) de C1. Or lors de l’exécution
l’objet référencé est de type C2 donc la méthode m effectivement appelée doit appartenir à la
classe C2 tout en respectant la signature déjà déterminée dans la phase de la compilation, d’où
le choix de m(float) de C2.
La classe Object est la classe dont dérive implicitement toute classe simple. En principe
lorsqu’on écrit :
class A{
……….
}
Exemple :
26
((Point) o).affiche() ;
Pour appeler m() par l’objet o, il ne suffit pas que cette dernière existe dans la classe type de
l’objet effectivement référencé par o mais m() doit exister déjà dans la classe Object, c’est le
mécanisme de la ligature dynamique mis en œuvre par le polymorphisme.
Les méthodes de la classe Object peuvent être utilisées telles quelles ou redéfinies. Parmi les
méthodes les plus utilisées, on peut citer:
toString()
getClass()
equals(Object o)
clone()
5.4 .1 toString
La méthode toString renvoie un objet de type String, cet objet contient le nom de la classe et
l’adresse de l’instance en hexadécimal précédée par @. La méthode toString de la classe
Object utilise une technique nommée fonction de rappel qui lui permettre d’être
automatiquement appelée en cas de besoin (d’une conversion implicite en chaine par
exemple).
5.4 .2 equals
La méthode equals permet de comparer les adresses de deux objets donnés, elle retourne une
valeur booléenne.
Exemple :
27
Chapitre 5. Interfaces et classes abstraites
28
I. Classes abstraites
1. Introduction
L'utilisation principale des classes et des méthodes abstraites est de réaliser l'abstraction en
Java. L'abstraction en Java est un concept important de la programmation orientée objet qui
nous permet de masquer les détails inutiles et de ne montrer que les informations nécessaires.
Cela nous permet de gérer la complexité en omettant ou en masquant des détails avec une idée
plus simple et de niveau supérieur.
Un exemple pratique d'abstraction peut être les freins de moto. Nous savons ce que fait le
frein. Lorsque nous appliquons le frein, la moto s'arrête. Cependant, le fonctionnement du
frein nous est caché.
Le principal avantage de cacher le fonctionnement du frein est que maintenant le fabricant
peut implémenter le frein différemment pour différentes motos, cependant, ce que fait le frein
sera le même.
Prenons un exemple qui nous aide à mieux comprendre l'abstraction en Java.
Une classe abstraite est une classe qui ne peut pas être instanciée, mais elle peut être utilisée
comme classe de base ou parente. Dans une classe abstraite on définit des champs, des
méthodes concrètes et des méthodes abstraites. Ces dernières sont des méthodes qui ne
possèdent pas de codes.
Exemple :
Abstract class C {
private int n ;
public void m()
{……..}
public abstract void f(float d) ;
}
C c ;//OK
C=new C() ; //erreur
class A extends C{
public void f(float d){
System.out.println(“Corps de la méthode ‘’) ;
}
}
29
A a=new A() ;//OK
C a=new A() ;//OK
Remarques :
Une classe abstraite peut avoir des constructeurs comme le cas des classes régulières. Et, nous
pouvons accéder au constructeur d'une classe abstraite à partir de ses classes filles en utilisant
le mot-clé super.
Exemple :
Dans cet exemple, nous avons utilisé le mot-clé super à l'intérieur du constructeur de la
classe Chat pour accéder au constructeur de sa classe de base Animal. Notez que le mot-clé
super doit toujours être la première instruction du constructeur de la sous-classe.
30
II. Interfaces
1. Introduction
Une interface en Java est une notion fondamentale, elle est massivement utilisée aussi bien
dans les APIs du JDK que par les développeurs Java expérimentés. Une interface en Java
représente un contrat qui une fois adopté par une classe, elle doit le respecter. Autrement dit,
une interface définit un ou plusieurs comportements d’une classe sans dire comment.
Au contraire d’une classe abstraite, aucune méthode dans une interface ne doit être
implémentée (on dit qu’une interface est une classe 100% abstraite) et par conséquence une
interface ne contient que des méthodes abstraites et des champs constants.
Pour créer une interface en Java, on utilise la syntaxe suivante :
Pour qu’une classe puisse adopter le contrat définit par une interface, elle suffit de
l’implémenter comme le suivant.
2. Implémentation d'interfaces
Lorsqu'une classe implémente une interface, elle doit exécuter les comportements
spécifiques de l'interface. Si une classe n'exécute pas tous les comportements de l'interface, la
classe doit se déclarer abstraite.
Une classe utilise le mot clé implements pour implémenter une interface. Le mot clé
implements apparaît dans la déclaration de classe à la suite de la partie extends de la
déclaration.
31
Les signatures de méthodes d'interface et le même type ou sous-type de retour
doivent être conservés lors de la redéfinition des méthodes.
Une classe d'implémentation elle-même peut être abstraite et si c'est le cas, les
méthodes d'interface n'ont pas besoin d'être implémentées.
Une interface peut étendre une autre interface de la même manière qu'une classe peut étendre
une autre classe. Le mot clé extends est utilisé pour étendre une interface et l'interface enfant
hérite des méthodes de l'interface parent. Les interfaces en java permettent de simuler
l’héritage multiple.
La notion d'interface est profondément modifiée en Java 8. Jusqu'à Java 7 une interface ne
peut posséder que des méthodes abstraites (donc des signatures de méthodes) et des
constantes. À partir de Java 8, on peut ajouter deux éléments supplémentaires dans une
interfaces : des méthodes statiques et des méthodes par défaut.
Comme on a déjà vu un appel d’une méthode statique se fait au travers de la classe, il n'a
besoin d'aucune instance pour être exécuté. Java 8 autorise des méthodes statiques dans les
interfaces, qui obéissent aux mêmes règles que celles que l'on trouve dans les classes
abstraites ou concrètes.
La notion de méthode par défaut est introduite par Java 8, et constitue une évolution
majeure du langage.
Syntaxe :
32
Au contraire des méthodes d’une interface, une méthode par défaut dans une interface
présente une implémentation. Si une interface possède des méthodes par défaut, toute classe
concrète qui l'implémente est libre de fournir sa propre implémentation de cette méthode par
défaut, ou de ne rien faire. Dans ce cas, les instances de cette classe utiliseront
l'implémentation par défaut fournie dans l'interface. Ce mécanisme n'existe qu'à partir de
Java 8.
33