Vous êtes sur la page 1sur 33

Université Sidi Mohamed Ben Abdellah de Fès

Faculté des Sciences Dhar Mehraz


Département d’Informatique
Sciences Mathématiques et Informatique
Année Universitaire : 2023/2024
S5

Module : Programmation Orientée Objet sous Java

Pr. Ismail EL BATTEOUI

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 ||.

2. Opérateurs d’incrémentation et de décrémentation

 ++i : a pour effet l’incrémentation de la valeur de i d’un pas de 1.


 i++ : incrémentation après un traitement donné.
 Idem pour i—et –i.

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.

II. Instructions de contrôle


Dans un programme Java, les instructions sont exécutées d’une manière séquentielle,
autrement dit dans l’ordre ou elles apparaissent. Or dans des nombreuses situations, un
programme doit effectuer des choix et des boucles. Pour ce faire, java dispose d’instructions
particulières nommées instructions de contrôle.

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 ]
}

Java 14: (Exemple)


switch (n)
{ case 0 -> System.out.println ("nul") ;
case 1 -> System.out.println ("un") ;
case 3 -> System.out.println ("trois") ;
}

3. Instruction do... while

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) ;
}
}

Question : Qu’est ce qu’il fait ce programme ?

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 :

public class Point{


private int x ; // abscisse
private int y ; // ordonnee
public void initialise (int abs, int ord){
x = abs ;
y = ord ;
}
public void deplace (int dx, int dy){
x += dx ;
y += dy ;
}
public void affiche (){
System.out.println ("Je suis un point de coordonnees " + x + " " +
y) ;
}
}

public class Test{


public static void main (String args[]){
Point a = new Point(); //instanciation de Point
a.initialise(1, 2) ;
a.affiche() ;
a.deplace(1, 1) ;
a.affiche() ;
Point b = new Point() ;
b.initialise (3, 4) ;
b.affiche() ;
}
}

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.

Point avec constructeur :

public class Point


private int x ;
private int y ;
{ public Point (int abs, int ord) // constructeur
{ x = abs ;
y = ord ;
}
public void deplace (int dx, int dy)
{ x += dx ;
y += dy ;
}
public void affiche ()
{ System.out.println ("Je suis un point de coordonnees " + x + " " +
y) ;
}
}
 Le mot clé public dans public static void main(String [] args) est obligatoire et ne
représente plus le mode d’accès ou portée mais une convention qui permet à la
machine virtuelle d’accéder à la méthode main ( ).
 On peut inverser l’ordre des mots-clés public et static.
 L’affichage dans Java est donné par l’instruction :
System.out.println(’’……’’)
 Println est l’abréviation de print line càd affichage suivi d’un retour à la ligne.
 System désigne une classe dans laquelle est défini un champ donnée out qui représente
la fenêtre console.
 Le champ out possède l’attribut static ce qui signifie qu’il est indépendant de tout
objet de type system.
 La méthode println est une méthode de la classe dont est issu le champ out (ou objet
out ) cette classe est nommée PrintStream.
PrintStream out ;

 Le JDK 5.0 a introduit une méthode printf permettant un affichage formaté.


 Une méthode ou une variable déclarée sans modificateur d’accès est disponible pour
toute autre classe du même package.
 La classe contenant la méthode main ( ) doit obligatoirement être publique afin que la
machine virtuelle y ait accès.

8
 Une classe n’ayant aucun mode d’accès reste accessible à toutes les classes du même
paquetage (même fichier source).

Les méthodes que comporte une classe peuvent être diviser en :

 Constructeurs
 Méthodes d’accès getXxxx
 Méthodes d’altération setXxxx

2. Champs et méthodes d’une classe

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

Exemples de méthodes de classes prédéfinies :

 Les méthodes Sqrt, sin, cos de la classe Math.

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.

Exemple : méthodes de classe fournissant l’identification d’une classe.

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.

On parle de surdéfinition (surcharge) lorsqu’un même symbole possède plusieurs


significations et on peut choisir une qu’en fonction du contexte.

Exemple : a+b

Selon le contexte, le symbole + ici joue le rôle d’un opérateur arithmétique.

La surdéfinition ou surcharge d’une méthode ou d’un constructeur permet de définir


plusieurs fois une même méthode ou constructeur avec des arguments différents.
Le compilateur choisit la méthode qui doit être appelée en fonction du nombre et du type des
arguments.

3.1 Surcharge de constructeur

Exemple 1:

‘’Ali’’,
This(pNom,‘’Ali‘’,0) ;

This(‘’Amrabet’’,‘’Soufiane ‘’,0) ;

3.2 Surcharge de méthodes

Exemple 2:

public class Overloading


{
public double test (int a, int b)

11
{
System.out.print ("Salut,");
return (a + b);
}

public double test (int a, double b)


{
System.out.print ("Salut, ");
return (a + b);
}

public double test (long a)


{
System.out.print ("Salut, ");
return a*a;
}
}

4. Méthodes accesseurs et mutateurs (setters et getters).

Voir la séance de cours

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.

2. Déclaration d’un tableau à un seul indice

Pour déclarer un tableau à une seule dimension, on utilise la syntaxe suivante :


type [] nom_tableau= new type[taille] ;
Ou :
type [] nom_tableau= {élément 1,élément 2,….,élément n} ;//déclaration explicite
Le programme suivant, TableDemo, crée un tableau d'entiers, place des valeurs dans le
tableau et imprime chaque valeur sur la sortie standard :
class TableDemo {
public static void main(String[] args) {
int[] T;
T = new int[10];
T[0] = 100;
T[1] = 200;
T[2] = 300;
T[3] = 400;
1
https://docs.oracle.com/

14
T[4] = 500;
T[5] = 600;
T[6] = 700;
T[7] = 800;
T[8] = 900;
T[9] = 1000;

System.out.println("Element à l’indice 0: "


+ T[0]);
System.out.println("Element à l’indice 1: "
+ T[1]);
System.out.println("Element à l’indice 2: "
+ T[2]);
System.out.println("Element à l’indice 3: "
+ T[3]);
System.out.println("Element à l’indice 4: "
+ T[4]);
System.out.println("Element à l’indice 5: "
+ T[5]);
System.out.println("Element à l’indice 6: "
+ T[6]);
System.out.println("Element à l’indice 7: "
+ T[7]);
System.out.println("Element à l’indice 8: "
+ T[8]);
System.out.println("Element à l’indice 9: "
+ T[9]);
}
}

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.

II. Tableaux à plusieurs indices


Java ne dispose pas, au contraire des autres langages de programmation, de la notion de
tableaux à plusieurs indices. Néanmoins, il permet d’émuler cette notion en créant des
tableaux de tableaux.

1. Déclaration

Les déclarations suivantes sont similaires.

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 :

int t [ ] [ ]={new int [2], new int[3]} ;

Le tableau t comporte deux éléments dont chacun est une référence à un autre tableau.
(Voir le schéma suivant)

 Référence au premier tableau de deux éléments : t[0].


 Référence au deuxième tableau de trois éléments : t[1].
 t[0][1] : deuxième éléments du premier tableau.
 t.length=2
 t[0].length=2.
 t[1].length=3
Remarque :
On peut obtenir les mêmes résultats obtenus dans l’exemple précédent en procédant ainsi :
int t[ ] [ ] ;
t=new int [2][ ] ;
int t1[ ]= new int[2] ;
int [ ] t2= new int [3] ;
t[0]=t1 ;
t[1]=t2 ;

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}} ;

Exercice : (voir la séance de cours)

Ecrire un programme Java qui :


 Crée et remplit un tableau des entiers à deux indices.
 Affiche le tableau.

3. Parcours de tableaux à plusieurs indices avec for..each

Pour parcourir un tableau à plusieurs dimensions avec for..each, il faut utiliser la syntaxe
suivante :

for(type [] n :t)
for(type m:n)

Avec type est le type des données de tableau et t le nom du tableau.

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 :

public class Point {


private float x,y;
public Point(float x, float y) {
this.x=x;
this.y=y;
}
public void affiche(){
System.out.print(‘’Coordonnées :’’+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 class Test {


public static void main(String [] args) {
Point3D p3D=new Point3D(1,2,3);
P3D.affiche();
System.out.println(“ , ‘’+this.z);
Point p=new Point(4,5);
p.affiche();
}
}

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.

2. Initialisation d’un objet dérivé

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 :

class B extends A { ..... }

La création d’un objet de type B se déroule en 6 étapes.


 Allocation mémoire pour un objet de type B ; il s’agit bien de l’intégralité de la
mémoire nécessaire pour un tel objet, et pas seulement pour les champs propres à B
(c’est-à-dire non hérités de A).
 Initialisation par défaut de tous les champs de B (aussi bien ceux hérités de A, que
ceux propres à B) aux valeurs "nulles" habituelles.
 Initialisation explicite, s’il y a lieu, des champs hérités de A, éventuellement,
exécution des blocs d’initialisation de A.
 Exécution du corps du constructeur de A.
 Initialisation explicite, s’il y a lieu, des champs propres à B, éventuellement,
exécution des blocs d’initialisation de B.

20
 Exécution du corps du constructeur de B.

3. Redéfinition et surdéfinition des méthodes

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) ;
}

3.2 Redéfinition des méthodes

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.

Reprenons l’exemple précédent :

public class Point {

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);
}
}

public class Test {


public static void main(String [] args ){
Point3D p3d=new Point3D(1,2,3);
p3d.affiche();
System.out.println(‘’Profondeur :’’+this.z) ;
}

L’appel de la méthode affiche() provoque un appel récursif de la méthode affiche() de la


classe Point3D au lieu de la méthode affiche() de la classe parente. Pour palier à ce problème,
il suffit d’utiliser le mot clé super comme le suivant :
22
public void affiche(){
super.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.

4. Redéfinition et héritage successif

Voir les travaux dirigés.

5. Polymorphisme

5.1 Introduction

Le polymorphisme est un concept fondamental dans l’orienté Objet, il consiste à modifier le


comportement d’une classe fille par rapport à sa classe parente et ce permet de compléter le
principe d’héritage. Le polymorphisme permet de manipuler les objets sans connaitre leurs
types. En effet, il ne s’agit pas de manipuler n’importe quel objet mais de prendre en
considération la relation : un objet d’une classe dérivée est un objet de sa classe parente. La
réciproque est fausse.

Exemple :

public class Personne {


public void parler(){
System.out.println(‘’Je parle’’) ;
}
}

Soient les deux classes filles suivantes :

public class Arabe extends Personne {


public void parler(){
System.out.println(‘’Je parle en arabe’’) ;
}

public class Americain extends Personne {

23
public void parler(){
System.out.println(‘’Je parle en anglais’’) ;
}

Personne p=new Personne() ;


p.parler() ;// affiche je parle

Arabe a=new Arabe() ;


a.parler() ;// affiche je parle en arabe

American am=new Américain() ;


am.parler() ;// affiche je parle en anglais

p=a ;
p.parler()//affiche je parle en arabe

Remarque :

 Le choix de la méthode dépend du type effectif de l’objet et non pas de sa référence.


 Les méthodes de portée privée ne supportent pas le polymorphisme.
Reprenons les classes Point et Point3D :

Point p=new Point(1,2) ;

Nous donne :

1 x
(Point) p
2 y

On peut aussi écrire :

p=new Point3D(3 ,4,5) ;


// p de type Point contient la référence à un objet de type Point3D

3 x
(Point) p
4 y

5 z

Java permet d’affecter à un objet non seulement la référence à un objet du type


correspondant mais aussi une référence à un objet d’un type hérité. Ce mécanisme est appelé,
en Java, la compatibilité par affectation.

24
Prenons maintenant les deux instructions suivantes :

Point p=new Point(1,2) ; //appel affiche de Point


Point p=new Point3D(1,2,3) ; //appel affiche de Point3D

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).

5.2 Polymorphisme, redéfinition et surdéfinition

Le polymorphisme se base sur la redéfinition des méthodes. Soit l’exemple suivant :

public class C1{


…………….
public void m(float x)
{…………}
}
public class C2 extends C1{
…………….
public void m(float x)
{…………..}
public void m(int n)
{…………..}
}
1. public class Main{
2. public static void main(String [] args){
3. C1 c=new C1();
4. C2 cc=new C2();
5. int n;
6. c.m(n);// appel m de C1
7. cc.m(n) ;// appel m(int) de C2
8. c=cc ; //c contient la référence à un objet C2

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.

5.3 Super-classe Object

La classe Object est la classe dont dérive implicitement toute classe simple. En principe
lorsqu’on écrit :

class A{
……….
}

C’est comme on a écrit :

class A extends Object{


……….
}
Une variable de type Object peut être utilisée pour référencer un objet de type quelconque.

Exemple :

Point p=new Point() ;


Point3D pd=new Point3D() ;
Rectangle r=new Rectangle();
Object o;
o=p;
o.affiche();// erreur de compilation
o=pd;
o=r;

Pour corriger l’erreur précèdent, il faut écrire :

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.

5.4 Méthodes de la classe Object

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 :

Object o1=new Point(1,2) ;


Object o2=new Point(1,2) ;
o1.equals(o2); // renvoie false

La méthode equals est souvent à redéfinir (voir la séance de cours).

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.

2. Classes et méthodes abstraites

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 qui contient une méthode abstraite est abstraite.


 Une méthode abstraite doit obligatoirement être déclarée public.
 Une classe dérivée d’une classe abstraite n’est pas obligée de définir toutes les
méthodes abstraites de sa classe parente, elle peut même n’en définir aucune. Dans ce
cas cette classe fille doit être déclarée abstract.
 Une classe dérivée d’une classe concrète peut être déclarée abstraite.
 Une classe abstraite peut avoir des constructeurs (non abstraits).

3. Constructeurs de classes abstraites

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 :

Abstract class Animal {


Public Animal(){
………….
}
}
public class Chat extends Animal {
public Chat(){
super();
…….
}

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 :

public interface Nom_Interface

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.

public class B extends A implements Nom_Interface

Lors de l'implémentation des interfaces, il existe plusieurs règles à respecter :


 Une classe peut implémenter plusieurs interfaces à la fois.
 Une classe ne peut étendre qu'une seule classe, mais implémenter de nombreuses
interfaces.
 Une interface peut étendre une autre interface, de la même manière qu'une classe peut
étendre une autre classe.
Lors de la redéfinition des méthodes définies dans les interfaces, il y a plusieurs règles à
suivre, citons à titre d’exemple :

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.

3. Extension des interfaces

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.

4. Java 8 et les interfaces

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.

4.1 Méthode statique

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.

4.2 Méthode par défaut

La notion de méthode par défaut est introduite par Java 8, et constitue une évolution
majeure du langage.

Syntaxe :

public interface NomInterface {


default type_retour nom_méthode (type param1,type param2,…….)
{………..}
……….
}

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

Vous aimerez peut-être aussi