0% ont trouvé ce document utile (0 vote)
52 vues36 pages

Document 2

Transféré par

aajarour1
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Thèmes abordés

  • Constructeurs,
  • Portabilité,
  • Expressions Lambda,
  • Classes,
  • Instructions Conditionnelles,
  • Méthodes par Défaut,
  • Interfaces,
  • Encapsulation,
  • Java 8,
  • Héritage
0% ont trouvé ce document utile (0 vote)
52 vues36 pages

Document 2

Transféré par

aajarour1
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Thèmes abordés

  • Constructeurs,
  • Portabilité,
  • Expressions Lambda,
  • Classes,
  • Instructions Conditionnelles,
  • Méthodes par Défaut,
  • Interfaces,
  • Encapsulation,
  • Java 8,
  • Héritage

Ecole supérieure de technologie d’Essaouira

Programmation Orientée Objet en JAVA


Préparé par :
Pr. Elmahdi ERRAJI
Filère : 2ème année Génie Informatique

Année universitaire : 2023 - 2024


Chapitre 1

Introduction

1.1 Présentation de Java


Java est un langage de programmation orienté objet, conçu avec l’idée de
permettre aux développeurs d’écrire un code unique pouvant être exécuté sur
n’importe quelle plateforme, sans modification. Cette capacité de fonctionner
sur plusieurs systèmes est rendue possible grâce à la Machine Virtuelle Java
(JVM), qui interprète le code Java en un code machine compréhensible par
l’ordinateur hôte.

1.1.1 Historique
Créé au début des années 1990 par une équipe dirigée par James Gosling
chez Sun Microsystems, Java a été initialement conçu pour les applications
de télévision interactive. Cependant, il s’est avéré être une solution idéale
pour le développement d’applications Internet, notamment avec l’essor du
World Wide Web.

1.1.2 Caractéristiques de Java


— Orienté Objet : Tout en Java est traité comme des objets, ce qui
facilite la gestion et la manipulation des données.
— Plateforme Indépendante : Grâce à la JVM, le code Java peut être
exécuté sur n’importe quelle machine, indépendamment du système
d’exploitation ou de l’architecture.
— Sécurisé : Java est conçu avec des fonctionnalités de sécurité inté-
grées, y compris un mécanisme de gestion des exceptions et l’absence
de pointeurs explicites.

1
— Performant : Bien que le code Java soit interprété, la JVM peut
exécuter le code compilé (bytecode) presque aussi rapidement que les
langages compilés comme C++.
— Syntaxe Familière : La syntaxe de Java est similaire à celle de C et
C++, ce qui facilite l’apprentissage pour les développeurs ayant une
expérience dans ces langages.

1.2 Pourquoi apprendre Java ?


Java est omniprésent, de l’informatique d’entreprise aux applications mo-
biles. En raison de sa portabilité, de sa robustesse et de sa sécurité, il est
adopté par de grandes entreprises pour développer des applications com-
plexes. De plus, avec l’explosion du développement d’applications Android,
la connaissance de Java est plus pertinente que jamais.
En apprenant Java, les étudiants se préparent à entrer dans un marché
du travail qui valorise la polyvalence, l’innovation et la portabilité entre dif-
férentes plateformes technologiques.

2
Chapitre 2

Architecture de Java

2.1 Introduction à l’Architecture de Java


L’architecture de Java est conçue pour être à la fois robuste et portable,
assurant que le code Java peut être exécuté de manière fiable sur n’importe
quelle plateforme. Cette architecture se compose principalement de la Ma-
chine Virtuelle Java (JVM), du bytecode, et des bibliothèques de classes
Java.

2.2 Machine Virtuelle Java (JVM)


La JVM est l’un des composants essentiels de l’architecture Java. Elle
agit comme une interface entre le code Java et le matériel de l’ordinateur sur
lequel le code est exécuté, garantissant ainsi la portabilité du code.

2.2.1 Rôle de la JVM


La JVM exécute le bytecode Java, qui est une version compilée du code
source écrit par les développeurs. Elle interprète ce bytecode et le traduit
en instructions machine, permettant ainsi au programme de s’exécuter sur
l’ordinateur hôte.

2.2.2 Portabilité
L’un des slogans de Java est "Write Once, Run Anywhere" (WORA), ce
qui signifie que le code Java, une fois écrit et compilé en bytecode, peut être
exécuté sur n’importe quelle machine équipée d’une JVM, indépendamment
du système d’exploitation ou de l’architecture matérielle.

3
2.3 Bytecode
Le bytecode est le langage intermédiaire dans lequel le code source Java
est compilé. Il est plus abstrait que le code machine, mais peut être rapide-
ment interprété ou compilé en code natif par la JVM.

2.3.1 Compilation et Interprétation


Lorsqu’un programme Java est compilé, le compilateur Java transforme
le code source en bytecode. Ce bytecode est ensuite interprété ou compilé à
la volée (Just-In-Time compilation) en code machine natif par la JVM.

2.4 Bibliothèques de Classes Java


Les bibliothèques de classes Java, également connues sous le nom de Java
API, sont un ensemble de bibliothèques fournies par Java pour effectuer des
tâches communes de programmation.

2.4.1 Java Standard Edition (SE) API


La Java SE API fournit des bibliothèques pour les tâches courantes telles
que les opérations d’entrée/sortie, la gestion des chaînes de caractères, la
manipulation des réseaux, et bien plus encore. Ces bibliothèques sont conçues
pour être utilisées dans n’importe quelle application Java, qu’il s’agisse d’une
application de bureau, d’un serveur web, ou d’une application mobile.

2.5 Conclusion
L’architecture de Java est conçue pour permettre aux développeurs de
créer des applications sécurisées, performantes, et portables. La compréhen-
sion de cette architecture est essentielle pour exploiter pleinement les capa-
cités du langage Java.

4
Chapitre 3

Syntaxe de Base de Java

3.1 Introduction
Comprendre la syntaxe de base de Java est la première étape essentielle
pour tout développeur débutant en Java. Ce chapitre explore les éléments
fondamentaux du langage, tels que les variables, les types de données, les
opérateurs, et les structures de contrôle.

3.2 Les Variables en Java


3.2.1 Définition et Déclaration
Une variable en Java est un espace de stockage nommé qui peut conte-
nir une donnée modifiable de type primitif ou une référence à un objet. La
déclaration d’une variable nécessite la spécification de son type de données
suivi de son nom.

int age;
String name;

3.2.2 Initialisation des Variables


L’initialisation d’une variable se fait en assignant une valeur à la variable
lors de sa déclaration ou ultérieurement.

int age = 20; // Déclaration et initialisation simultanée


String name; // Déclaration
name = "Alice"; // Initialisation

5
3.2.3 Types de Variables
Les variables en Java peuvent être classées en trois catégories :

Variables Locales
Ce sont des variables déclarées dans le corps d’une méthode et sont ac-
cessibles uniquement à l’intérieur de cette méthode.

void maMethode() {
int x = 10; // Variable locale
}

Variables d’Instance
Ce sont des variables déclarées dans une classe mais en dehors de toute
méthode. Elles sont accessibles par toutes les méthodes d’instance de la
classe.

public class Etudiant {


String nom; // Variable d’instance
}

Variables de Classe ou Statiques


Ce sont des variables déclarées à l’intérieur d’une classe avec le mot-clé
static. Elles sont partagées par toutes les instances de la classe.

public class Mathematiques {


static double PI = 3.14159; // Variable de classe
}

3.2.4 Type Primitif et Type Référence


Types Primitifs
Java propose huit types de données primitifs : byte, short, int, long,
float, double, char, et boolean.

int entier = 42;


char caractere = ’A’;
boolean estVrai = true;

6
Types Référence
Les types référence sont utilisés pour stocker les adresses mémoire des
objets. Les classes, les interfaces, les tableaux, et les énumérations sont des
types de référence.

String chaine = "Bonjour";


int[] tableau = {1, 2, 3, 4};

3.2.5 Conversion de Types


En Java, vous pouvez convertir des variables d’un type à un autre, sous
réserve de compatibilité des types.

Conversion Implicite
Java convertit automatiquement le type de données de plus petite taille
au type de plus grande taille.

int i = 100;
long l = i; // Conversion implicite de int à long

Conversion Explicite (Casting)


Lorsque vous convertissez un type de données de plus grande taille à un
type de plus petite taille, vous devez effectuer un casting.

double d = 100.04;
int i = (int) d; // Casting explicite de double à int

3.3 Les Opérateurs en Java


3.3.1 Introduction
Les opérateurs sont des symboles spéciaux qui représentent des calculs
entre des variables et des valeurs. Java propose une variété d’opérateurs pour
effectuer des opérations telles que l’arithmétique, la comparaison, la logique,
et plus encore.

7
3.3.2 Types d’Opérateurs
Opérateurs Arithmétiques
Ces opérateurs sont utilisés pour effectuer des opérations arithmétiques.

int a = 10, b = 20;


int somme = a + b; // Addition
int difference = a - b; // Soustraction
int produit = a * b; // Multiplication
int quotient = b / a; // Division
int reste = b % a; // Modulo (reste de la division)

Opérateurs de Comparaison
Ces opérateurs sont utilisés pour comparer deux valeurs.

boolean egal = (a == b); // Égal à


boolean nonEgal = (a != b); // Non égal à
boolean plusGrand = (a > b); // Plus grand que
boolean plusPetit = (a < b); // Plus petit que
boolean plusGrandOuEgal = (a >= b); // Plus grand ou égal à
boolean plusPetitOuEgal = (a <= b); // Plus petit ou égal à

Opérateurs Logiques
Ces opérateurs sont utilisés pour effectuer des opérations logiques sur des
variables booléennes.

boolean result1 = (a == 10) && (b == 20); // ET logique


boolean result2 = (a == 10) || (b == 30); // OU logique
boolean result3 = !(a == 10); // NON logique

Opérateurs d’Assignation
Ces opérateurs attribuent une valeur à une variable.

a = 10; // Assignation
a += 10; // Équivaut à a = a + 10
a -= 5; // Équivaut à a = a - 5

8
3.3.3 Priorité des Opérateurs
La priorité des opérateurs détermine l’ordre dans lequel les opérations
sont effectuées. Voici un tableau indiquant la priorité des opérateurs, du plus
élevé au plus bas.

Priorité Opérateur Description


1 ()[] Parenthèses, crochets, et accès à un tableau
2 ++ – + - ! Opérateurs unaires
3 */% Multiplication, division, modulo
4 +- Addition, soustraction
5 < <= > >= Opérateurs de comparaison
6 == != Égalité et non égalité
7 && ET logique
8 || OU logique
9 = += -= *= /= Opérateurs d’assignation

Table 3.1 – Priorité des opérateurs en Java

3.4 Les Structures de Contrôle en Java


3.4.1 Introduction
Les structures de contrôle permettent à votre programme de prendre des
décisions et de répéter des actions. Elles sont essentielles pour ajouter de la
logique et de la flexibilité à vos programmes.

3.4.2 Instructions Conditionnelles


La Structure if
La structure if permet d’exécuter un bloc de code seulement si une condi-
tion donnée est vraie.

int age = 20;


if (age >= 18) {
[Link]("Vous êtes majeur.");
}

9
La Structure if-else
La structure if-else permet d’exécuter un bloc de code si une condition
est vraie et un autre bloc si elle est fausse.

int age = 16;


if (age >= 18) {
[Link]("Vous êtes majeur.");
} else {
[Link]("Vous êtes mineur.");
}

La Structure if-else if-else


La structure if-else if-else est utilisée pour tester plusieurs condi-
tions.

int note = 75;


if (note < 50) {
[Link]("Échec");
} else if (note < 60) {
[Link]("Passable");
} else {
[Link]("Réussite");
}

La Structure switch
La structure switch permet d’exécuter un bloc de code parmi plusieurs
possibles en fonction de la valeur d’une expression.

int jour = 2;
switch (jour) {
case 1:
[Link]("Lundi");
break;
case 2:
[Link]("Mardi");
break;
// ...
default:
[Link]("Jour invalide");
}

10
3.4.3 Boucles
La Boucle for
La boucle for est utilisée pour répéter un bloc de code un certain nombre
de fois.

for (int i = 0; i < 5; i++) {


[Link]("Iteration " + i);
}

La Boucle while
La boucle while répète un bloc de code tant qu’une condition est vraie.

int i = 0;
while (i < 5) {
[Link]("Iteration " + i);
i++;
}

La Boucle do-while
La boucle do-while est similaire à la boucle while, mais elle exécute le
bloc de code au moins une fois.

int i = 0;
do {
[Link]("Iteration " + i);
i++;
} while (i < 5);

3.5 Conclusion
La maîtrise de la syntaxe de base de Java, des opérateurs, et des struc-
tures de contrôle est essentielle pour écrire des programmes efficaces. Ce
chapitre constitue une introduction à ces concepts fondamentaux. Les cha-
pitres suivants approfondiront ces notions et introduiront des concepts plus
avancés.

11
Chapitre 4

Tableaux en Java

4.1 Introduction
Les tableaux en Java sont des objets qui stockent des éléments de même
type en mémoire continue. Ils sont utilisés pour stocker des collections de
données, et leur taille est définie lors de la création. Ce chapitre explore la
création, l’initialisation, et la manipulation des tableaux en Java.

4.2 Déclaration et Création de Tableaux


4.2.1 Déclaration
Un tableau peut être déclaré en spécifiant le type de ses éléments suivi
de crochets.
int[] myArray;

4.2.2 Création
Après la déclaration, il est nécessaire de créer le tableau en spécifiant sa
taille.
myArray = new int[10];

4.2.3 Déclaration et Création en une Étape


Il est également possible de déclarer et de créer un tableau en une seule
étape.
int[] myArray = new int[10];

12
4.3 Initialisation de Tableaux
4.3.1 Initialisation lors de la Création
On peut initialiser un tableau lors de sa création en spécifiant les valeurs
des éléments entre accolades.

int[] myArray = {1, 2, 3, 4, 5};

4.3.2 Initialisation Post-Création


Les éléments d’un tableau peuvent être initialisés individuellement en
utilisant leur index.

myArray[0] = 1;
myArray[1] = 2;

4.4 Manipulation de Tableaux


4.4.1 Accéder aux Éléments
On peut accéder à un élément d’un tableau en utilisant son index.

int firstElement = myArray[0];

4.4.2 Parcourir un Tableau


On peut parcourir un tableau en utilisant une boucle for ou foreach.

// Avec for
for (int i = 0; i < [Link]; i++) {
[Link](myArray[i]);
}

// Avec foreach
for (int element : myArray) {
[Link](element);
}

13
4.5 Tableaux Multidimensionnels
Java supporte également les tableaux multidimensionnels. Un tableau bi-
dimensionnel, par exemple, peut être considéré comme une matrice.

int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

4.6 Conclusion
Les tableaux sont un moyen efficace de stocker et de manipuler des col-
lections d’éléments. En comprenant comment créer, initialiser, et manipuler
des tableaux en Java, les étudiants peuvent gérer efficacement des ensembles
de données de taille fixe dans leurs programmes.

14
Chapitre 5

Les Chaînes de Caractères en


Java

5.1 Introduction
En Java, les chaînes de caractères, représentées par la classe String, sont
une séquence immuable de caractères. Ce chapitre explore comment créer,
manipuler, et opérer sur les objets String en Java.

5.2 Création de Chaînes de Caractères


5.2.1 Littéraux de Chaînes
Une chaîne de caractères peut être créée directement en utilisant des
littéraux de chaînes, qui sont définis entre guillemets doubles.
String greeting = "Bonjour!";

5.2.2 Constructeur de la Classe String


On peut également créer une chaîne de caractères en utilisant le construc-
teur de la classe String.
String greeting = new String("Bonjour!");

5.3 Immutabilité des Chaînes


Les objets String sont immuables en Java, ce qui signifie que leur contenu
ne peut pas être modifié une fois qu’ils sont créés. Toute opération de mo-

15
dification sur une chaîne de caractères entraîne la création d’une nouvelle
chaîne.

String str1 = "Java";


str1 = str1 + " Programming"; // Crée une nouvelle chaîne

5.4 Méthodes Communes de la Classe String


5.4.1 Création et Initialisation de Chaînes
On peut créer une chaîne de caractères en Java simplement comme suit :

String maChaine = "Bonjour le monde!";

5.4.2 Méthodes Communes


length()
La méthode length() retourne la longueur de la chaîne.

int longueur = [Link]();

charAt(int index)
La méthode charAt() retourne le caractère à un index spécifique.

char caractere = [Link](0); // ’B’

substring(int beginIndex, int endIndex)


La méthode substring() extrait une sous-chaîne à partir d’un index de
début jusqu’à un index de fin.

String sousChaine = [Link](0, 7); // "Bonjour"

concat(String str)
La méthode concat() concatène la chaîne spécifiée à la fin de la chaîne
courante.

String nouvelleChaine = [Link](" Comment ça va ?");

16
indexOf(String str) et lastIndexOf(String str)
Les méthodes indexOf() et lastIndexOf() retournent l’index de la pre-
mière ou dernière occurrence de la sous-chaîne spécifiée, respectivement.

int index = [Link]("monde"); // 8

equals(Object obj)
La méthode equals() compare deux chaînes pour vérifier si elles sont
identiques.

boolean egal = [Link]("Bonjour le monde!"); // true

replace(char oldChar, char newChar)


La méthode replace() remplace toutes les occurrences d’un caractère
par un autre.

String chaineRemplacee = [Link](’o’, ’a’); // "Banjaur le mande!"

toLowerCase() et toUpperCase()
Les méthodes toLowerCase() et toUpperCase() convertissent respecti-
vement tous les caractères de la chaîne en minuscules ou en majuscules.

String enMinuscules = [Link](); // "bonjour le monde!"


String enMajuscules = [Link](); // "BONJOUR LE MONDE!"

trim()
La méthode trim() supprime les espaces blancs au début et à la fin de
la chaîne.

String chaineTrim = " Espace au début et à la fin ".trim();

5.5 Les Classes StringBuffer et StringBuilder


En Java, les objets de type String sont immuables, ce qui signifie que
chaque opération de modification de chaîne crée une nouvelle instance. Pour
des manipulations de chaînes intensives, cela peut entraîner des coûts de
performance. Les classes StringBuffer et StringBuilder fournissent une
alternative mutable.

17
5.5.1 StringBuffer
StringBuffer est une classe qui permet de manipuler des chaînes de
caractères de manière mutable. Elle est thread-safe, ce qui signifie que les
méthodes sont synchronisées pour être utilisées dans un environnement mul-
tithread.

Création et Manipulation
Un StringBuffer peut être créé et manipulé de la manière suivante :
StringBuffer buffer = new StringBuffer("Bonjour");
[Link](" le monde");
String resultat = [Link](); // "Bonjour le monde"

5.5.2 StringBuilder
StringBuilder est similaire à StringBuffer, mais sans garantie de syn-
chronisation. Il est donc plus rapide dans un environnement single-thread.

Création et Manipulation
Un StringBuilder peut être créé et manipulé de la manière suivante :
StringBuilder builder = new StringBuilder("Bonjour");
[Link](" le monde");
String resultat = [Link](); // "Bonjour le monde"

5.5.3 Méthodes Communes


Les méthodes communes pour StringBuffer et StringBuilder incluent :

append(String str)
Ajoute une chaîne à la fin du contenu actuel.
[Link]("!");
[Link]("!");

insert(int offset, String str)


Insère une chaîne à une position spécifiée.
[Link](7, " cher");
[Link](7, " cher");

18
delete(int start, int end)
Supprime une séquence de caractères.

[Link](0, 8);
[Link](0, 8);

reverse()
Inverse la séquence de caractères.

[Link]();
[Link]();

Les classes StringBuffer et StringBuilder sont des alternatives mu-


tables aux chaînes de caractères immuables de Java. Elles sont particuliè-
rement utiles lorsque de nombreuses opérations de manipulation de chaînes
sont nécessaires, réduisant ainsi l’overhead de création de nombreux objets
String.

5.6 Conclusion
Les chaînes de caractères sont l’un des types de données les plus utilisés
en Java. La compréhension des concepts relatifs à la classe String, ainsi
que l’utilisation efficace de ses méthodes et des classes alternatives comme
StringBuilder, sont essentielles pour la manipulation efficace des données
textuelles en Java.

19
Chapitre 6

La Programmation Orientée
Objet en Java

La programmation orientée objet (POO) est un paradigme de program-


mation qui utilise des "objets" et des classes pour structurer le code de
manière plus flexible et réutilisable. Java, étant un langage orienté objet par
excellence, offre des mécanismes pour mettre en œuvre efficacement la POO.

6.1 Motivation
6.1.1 Pourquoi la POO ?
La POO permet de structurer le code en unités modulaires appelées
classes, qui peuvent être réutilisées et étendues dans différents projets. Cela
favorise le développement rapide, facilite la maintenance et rend le code plus
compréhensible.

6.2 Les Classes en Java


En Java, une classe est un modèle qui permet de définir la structure et
le comportement d’une catégorie d’objets. Elle spécifie comment les objets
créés à partir de la classe doivent se comporter en définissant des attributs
(variables) et des méthodes (fonctions).

6.2.1 Définition d’une Classe


Pour créer une classe en Java, on utilise le mot-clé class suivi du nom
de la classe. Le corps de la classe est délimité par des accolades {}.

20
public class Animal {
// Attributs et méthodes
}

6.2.2 Attributs
Les attributs, également appelés variables d’instance, définissent les pro-
priétés ou caractéristiques d’une classe. Ils sont déclarés à l’intérieur de la
classe mais en dehors de toute méthode.

public class Animal {


String nom;
int age;
}

6.2.3 Méthodes
Les méthodes définissent le comportement de la classe et spécifient ce
qu’un objet créé à partir de la classe peut faire.

public class Animal {


String nom;
int age;

void faireDuBruit() {
[Link]("L’animal fait du bruit.");
}
}

6.2.4 Constructeurs
Un constructeur est une méthode spéciale qui est utilisée pour initialiser
un objet lors de sa création. Le nom du constructeur doit être identique à celui
de la classe. Si aucun constructeur n’est défini, Java fournit un constructeur
par défaut.

public class Animal {


String nom;
int age;

// Constructeur

21
public Animal(String nom, int age) {
[Link] = nom;
[Link] = age;
}
}

6.2.5 Instanciation
L’instanciation est le processus de création d’un objet à partir d’une classe
en utilisant le mot-clé new et le constructeur de la classe.

Animal monAnimal = new Animal("Léo", 3);

6.2.6 Accès aux Membres


Après l’instanciation, les attributs et méthodes de la classe peuvent être
accédés via l’objet créé en utilisant l’opérateur . (point).

[Link]("Nom de l’animal : " + [Link]);


[Link]();

Les classes en Java fournissent un moyen de regrouper des données et des


fonctions qui opèrent sur ces données en une seule entité cohérente. Elles sont
à la base de la programmation orientée objet et permettent une abstraction
et une modularité du code.

6.3 L’Héritage en Java


6.3.1 Introduction
L’héritage est un des piliers de la programmation orientée objet (POO)
qui permet à une classe (classe dérivée ou sous-classe) d’hériter des attributs
et des méthodes d’une autre classe (classe de base ou superclasse). L’héritage
vise à favoriser la réutilisation du code et à établir une relation de type "est-
un" entre la sous-classe et la superclasse.

6.3.2 Utilisation de l’Héritage


Syntaxe
L’héritage en Java est réalisé en utilisant le mot-clé extends.

22
public class Mammifere {
void respirer() {
[Link]("Respire avec des poumons.");
}
}

public class Chien extends Mammifere {


void aboyer() {
[Link]("Le chien aboie.");
}
}

Accès aux Méthodes Héritées


Une sous-classe hérite des méthodes de la superclasse et peut les appeler
directement.

Chien monChien = new Chien();


[Link](); // Affiche "Respire avec des poumons."

6.3.3 Le Mot-clé super


Le mot-clé super en Java est une référence à l’objet de la superclasse
immédiate. Il peut être utilisé pour invoquer les méthodes de la superclasse
qui sont masquées par les méthodes de la sous-classe.

public class Chien extends Mammifere {


void respirer() {
[Link]("Le chien respire bruyamment.");
}

void respirerCommeMammifere() {
[Link](); // Appelle la méthode respirer de Mammifere
}
}

6.3.4 Surcharge et Redéfinition


Redéfinition de Méthodes (Override)
La redéfinition de méthodes, ou "override", permet à une sous-classe de
fournir une implémentation spécifique pour une méthode qui est déjà définie

23
dans sa superclasse ou dans une interface qu’elle implémente. La méthode
dans la sous-classe doit avoir la même signature que celle dans la superclasse.
— Annotations : Il est recommandé d’utiliser l’annotation @Override
pour indiquer explicitement qu’une méthode est redéfinie. Cela permet
au compilateur de vérifier la méthode et d’assurer la cohérence.
— Accès : La visibilité de la méthode redéfinie dans la sous-classe ne peut
pas être plus restrictive que celle de la méthode dans la superclasse.

public class Animal {


void faireDuBruit() {
[Link]("L’animal fait du bruit.");
}
}

public class Chien extends Animal {


@Override
void faireDuBruit() {
[Link]("Le chien aboie.");
}
}

Surcharge de Méthodes (Overload)


La surcharge de méthodes, ou "overloading", permet à une classe d’avoir
plusieurs méthodes ayant le même nom mais avec des listes de paramètres
différentes (différents types, nombre ou ordre de paramètres). La surcharge
de méthodes est utilisée pour créer des méthodes qui réalisent des tâches
similaires mais avec des types de données différents.
— Signature : Les méthodes surchargées doivent différer dans le type,
le nombre, ou l’ordre des paramètres. Le type de retour ne suffit pas
à différencier des méthodes surchargées.
— Visibilité : Les méthodes surchargées peuvent avoir des niveaux de
visibilité différents.

public class Calculatrice {


int somme(int a, int b) {
return a + b;
}

double somme(double a, double b) {


return a + b;

24
}

int somme(int a, int b, int c) {


return a + b + c;
}
}

Comparaison
Bien que la surcharge et la redéfinition de méthodes impliquent toutes
deux d’avoir plusieurs méthodes avec le même nom, elles sont différentes
dans leur utilisation et leur but.
— Surcharge : Même classe, signatures différentes, indépendante de
l’héritage.
— Redéfinition : Classes parent-enfant, même signature, implique l’hé-
ritage.
La surcharge et la redéfinition de méthodes en Java permettent aux déve-
loppeurs de créer des systèmes plus flexibles et évolutifs. En comprenant ces
concepts, les programmeurs peuvent concevoir des classes qui sont faciles à
étendre et à maintenir.

6.3.5 Héritage et Constructeurs


Lorsqu’une classe hérite d’une autre classe en Java, les constructeurs de
la classe de base ne sont pas hérités par la classe dérivée. Cependant, les
constructeurs de la superclasse peuvent être appelés à partir de la sous-classe.

Appel du Constructeur de la Superclasse


Lorsqu’une instance de la sous-classe est créée, le constructeur de la su-
perclasse est appelé en premier. Par défaut, Java appelle le constructeur sans
paramètre de la superclasse. Si la superclasse ne dispose pas d’un construc-
teur sans paramètre et que vous ne spécifiez pas le constructeur à appeler,
une erreur de compilation se produit.
— Utilisation de super : Le mot-clé super est utilisé pour appeler
explicitement le constructeur de la superclasse. Cet appel doit être la
première instruction dans le constructeur de la sous-classe.

public class Animal {


Animal() {
[Link]("Un animal est créé.");
}

25
}

public class Chien extends Animal {


Chien() {
super(); // Appelle le constructeur de la classe Animal
[Link]("Un chien est créé.");
}
}

Constructeurs avec Paramètres


Si la superclasse a des constructeurs avec des paramètres, vous pouvez
les appeler en utilisant également le mot-clé super avec les arguments ap-
propriés.

public class Animal {


Animal(String nom) {
[Link]("Un animal est créé: " + nom);
}
}

public class Chien extends Animal {


Chien(String nom) {
super(nom); // Appelle le constructeur de la classe Animal avec un paramètre
[Link]("Un chien est créé: " + nom);
}
}

Ordre d’Initialisation
L’ordre d’initialisation des constructeurs est important en Java. Lors-
qu’une sous-classe est instanciée, les éléments suivants sont appelés dans
l’ordre :
1. Les initialisateurs de variable de la superclasse
2. Le constructeur de la superclasse
3. Les initialisateurs de variable de la sous-classe
4. Le constructeur de la sous-classe

26
6.3.6 Masquage des Attributs de la Superclasse
Le masquage des attributs de la superclasse, également connu sous le nom
de "shadowing", se produit lorsque une sous-classe définit un attribut ayant
le même nom qu’un attribut dans sa superclasse. Dans ce cas, l’attribut de
la sous-classe masque l’attribut de la superclasse.

Comprendre le Masquage
Lorsque vous accédez à un attribut masqué à partir d’une méthode d’ins-
tance dans la sous-classe, c’est l’attribut de la sous-classe qui est utilisé et
non celui de la superclasse.

public class Animal {


String nom = "Animal générique";
}

public class Chien extends Animal {


String nom = "Chien spécifique";

void afficherNom() {
[Link](nom); // Affiche "Chien spécifique"
}
}

Accéder à l’Attribut Masqué


Vous pouvez accéder à l’attribut masqué de la superclasse en utilisant le
mot-clé super.

public class Chien extends Animal {


String nom = "Chien spécifique";

void afficherNoms() {
[Link](nom); // Affiche "Chien spécifique"
[Link]([Link]); // Affiche "Animal générique"
}
}

Différences avec la Redéfinition de Méthodes


Le masquage des attributs est différent de la redéfinition de méthodes.
La redéfinition concerne le changement de l’implémentation d’une méthode

27
héritée, tandis que le masquage concerne les attributs ayant le même nom
dans la hiérarchie de classes.
— Méthodes : Les méthodes sont liées dynamiquement au moment de
l’exécution, permettant le polymorphisme.
— Attributs : Les attributs sont liés statiquement au moment de la
compilation. L’attribut utilisé est déterminé par le type de référence
et non par le type de l’objet au moment de l’exécution.

Utilisation du mot-clé super


Le mot-clé super en Java est une référence à l’objet de la superclasse im-
médiate. Il peut être utilisé pour accéder aux attributs, méthodes et construc-
teurs de la superclasse qui sont masqués ou redéfinis dans la sous-classe.
— Accéder aux Attributs Masqués : Lorsqu’un attribut de la super-
classe est masqué par un attribut de la sous-classe ayant le même nom,
super peut être utilisé pour accéder à l’attribut de la superclasse.
public class Animal {
String nom = "Animal générique";
}

public class Chien extends Animal {


String nom = "Chien spécifique";

void afficherNoms() {
[Link](nom); // Affiche "Chien spécifique"
[Link]([Link]); // Affiche "Animal générique"
}
}
— Accéder aux Méthodes Masquées : De manière similaire, super
peut être utilisé pour appeler une méthode de la superclasse qui a été
redéfinie dans la sous-classe.
— Appeler le Constructeur de la Superclasse : super peut égale-
ment être utilisé pour appeler le constructeur de la superclasse depuis
le constructeur de la sous-classe.
Bien que les constructeurs ne soient pas hérités dans le sens tradition-
nel, comprendre comment et quand les constructeurs de la superclasse sont
appelés est essentiel pour créer des classes bien conçues et éviter les erreurs
courantes en Java.

28
6.3.7 Limitations de l’Héritage
Bien que l’héritage soit un outil puissant pour la réutilisation du code et
la modélisation des relations entre les objets, il présente certaines limitations
et restrictions en Java.

Héritage Simple
Java ne supporte pas l’héritage multiple, ce qui signifie qu’une classe ne
peut hériter que d’une seule superclasse. Cette restriction évite la complexité
et les ambiguïtés liées à l’héritage de plusieurs classes.

public class A { /* ... */ }


public class B extends A { /* ... */ } // Correct
// public class C extends A, B { /* ... */ } // Erreur de compilation

Final Classes et Méthodes


Java permet d’utiliser le mot-clé final pour indiquer qu’une classe ou
une méthode ne peut pas être étendue ou redéfinie respectivement.
— Final Classes : Une classe déclarée comme final ne peut pas être
héritée.
— Final Methods : Une méthode déclarée comme final ne peut pas
être redéfinie dans une sous-classe.

public final class A { /* ... */ }


// public class B extends A { /* ... */ } // Erreur de compilation

Accès Privé
Les membres déclarés comme private dans une superclasse ne sont pas
accessibles directement dans les sous-classes. Ils ne sont pas hérités dans le
sens traditionnel.

public class A {
private int x;
}

public class B extends A {


void afficherX() {
// [Link](x); // Erreur de compilation
}
}

29
Constructeurs
Les constructeurs ne sont pas hérités dans les sous-classes. Cependant, le
constructeur de la superclasse est appelé lors de l’instanciation d’un objet de
la sous-classe.

Association versus Héritage


Dans certains cas, utiliser la composition (association) peut être plus
approprié que l’héritage. L’héritage représente une relation "est-un" tandis
que la composition représente une relation "a-un". Par exemple, plutôt que
de dire qu’une voiture "est-un" moteur, il est plus logique de dire qu’une
voiture "a-un" moteur.
Comprendre les limitations de l’héritage est essentiel pour utiliser efficace-
ment la programmation orientée objet en Java. En étant conscient des restric-
tions et en choisissant judicieusement entre l’héritage et la composition, les
développeurs peuvent concevoir des systèmes plus flexibles et maintenables.
L’héritage en Java permet la réutilisation du code et établit une hiérar-
chie naturelle entre les classes. Bien qu’il soit puissant, son utilisation doit
être réfléchie pour éviter la complexité et favoriser la modularité et l’encap-
sulation.

6.4 Les Classes Abstraites en Java


En Java, une classe abstraite est une classe qui ne peut pas être instanciée
directement. Elle sert de base pour d’autres classes et peut contenir des mé-
thodes abstraites, c’est-à-dire des méthodes déclarées sans implémentation.
Les classes abstraites sont utilisées pour représenter des entités abstraites et
définir un contrat pour les classes dérivées.

6.4.1 Déclaration de Classes Abstraites


On déclare une classe abstraite en utilisant le mot-clé abstract avant le
mot-clé class.

public abstract class Animal {


String nom;

public abstract void faireDuBruit();


}

30
6.4.2 Méthodes Abstraites
Les méthodes abstraites sont déclarées sans corps dans une classe abs-
traite. Les classes concrètes qui héritent d’une classe abstraite doivent fournir
une implémentation pour toutes ses méthodes abstraites.

public abstract void faireDuBruit();

6.4.3 Héritage et Classes Abstraites


Implémentation des Méthodes Abstraites
Lorsqu’une classe concrète hérite d’une classe abstraite, elle doit implé-
menter toutes les méthodes abstraites de la classe abstraite.

public class Chien extends Animal {


@Override
public void faireDuBruit() {
[Link]("Le chien aboie.");
}
}

Héritage Multiple
Contrairement aux interfaces, Java ne permet pas l’héritage multiple avec
les classes, y compris les classes abstraites. Une classe ne peut hériter que
d’une seule classe abstraite.

6.4.4 Utilisation de Classes Abstraites


Bien qu’une classe abstraite ne puisse pas être instanciée directement,
une référence de type classe abstraite peut être utilisée pour pointer vers un
objet de l’une de ses sous-classes.

Animal monAnimal = new Chien();


[Link](); // Affiche "Le chien aboie."

6.4.5 Classes Abstraites vs Interfaces


Les classes abstraites sont souvent comparées aux interfaces. Quelques
différences notables sont :
— Une classe peut hériter de plusieurs interfaces, mais seulement d’une
classe abstraite.

31
— Une classe abstraite peut avoir des variables d’instance et des mé-
thodes avec des implémentations, tandis qu’une interface ne peut
contenir que des constantes et des méthodes abstraites.
Les classes abstraites permettent de définir un modèle pour des classes
apparentées tout en empêchant l’instanciation directe. Elles sont particuliè-
rement utiles pour partager du code tout en obligeant les classes dérivées à
suivre un certain contrat.

6.4.6 Polymorphisme
Le polymorphisme est un concept fondamental de la programmation orien-
tée objet qui permet à des objets de types différents d’être traités comme des
objets d’un type commun. En Java, le polymorphisme se manifeste principa-
lement sous deux formes : le polymorphisme de compile (ou surcharge) et le
polymorphisme de runtime (ou substitution).

Polymorphisme de Compile : Surcharge


La surcharge de méthodes (ou overloading) permet à plusieurs méthodes
dans la même classe d’avoir le même nom mais des listes de paramètres
différentes.

public class Calculateur {


public int somme(int a, int b) {
return a + b;
}

public double somme(double a, double b) {


return a + b;
}
}

Dans cet exemple, la méthode somme est surchargée pour accepter soit
deux entiers, soit deux doubles.

Polymorphisme de Runtime : Substitution


La substitution de méthodes (ou overriding) permet à une méthode dans
une sous-classe d’avoir la même signature que celle de sa superclasse. Cela
permet à une instance de la sous-classe d’être utilisée là où une instance de
la superclasse est attendue.

32
public class Animal {
public void faireDuBruit() {
[Link]("Un animal fait du bruit");
}
}

public class Chien extends Animal {


@Override
public void faireDuBruit() {
[Link]("Le chien aboie");
}
}

public class TestPolymorphisme {


public static void main(String[] args) {
Animal a = new Chien();
[Link](); // Affiche "Le chien aboie"
}
}

Dans cet exemple, bien que la référence a soit de type Animal, elle pointe
vers une instance de Chien, et la méthode faireDuBruit de la classe Chien
est appelée.

Upcasting et Downcasting
Le polymorphisme permet également le casting entre types. L’upcasting
convertit un objet de sous-classe en objet de superclasse, tandis que le down-
casting convertit un objet de superclasse en objet de sous-classe.
— Upcasting : Il est toujours sûr et est effectué implicitement.
— Downcasting : Il doit être effectué explicitement et peut générer une
exception ClassCastException s’il est incorrect.
Le polymorphisme augmente la flexibilité et le maintien du code en per-
mettant l’utilisation de types génériques. Cela facilite l’extension des sys-
tèmes existants et encourage la réutilisation du code.

6.4.7 Interfaces
Les interfaces sont un moyen de spécifier un contrat pour les classes sans
imposer une hiérarchie de classes. En Java, une interface est une collection de
méthodes abstraites (sans corps) et de constantes. Les interfaces permettent

33
à Java d’approcher la notion d’héritage multiple, car une classe peut implé-
menter plusieurs interfaces.

Définition et Implémentation
Une interface est définie en utilisant le mot-clé interface, et une classe
implémente une interface en utilisant le mot-clé implements.

public interface Volant {


void voler();
}

public class Oiseau implements Volant {


@Override
public void voler() {
[Link]("L’oiseau vole");
}
}

Héritage Multiple avec les Interfaces


Contrairement à l’héritage de classes, une classe peut implémenter plu-
sieurs interfaces, permettant ainsi une forme d’héritage multiple.

public interface Nageant {


void nager();
}

public class Canard implements Volant, Nageant {


@Override
public void voler() {
[Link]("Le canard vole");
}

@Override
public void nager() {
[Link]("Le canard nage");
}
}

34
Méthodes par Défaut et Méthodes Statiques
Depuis Java 8, les interfaces peuvent avoir des méthodes par défaut (avec
une implémentation) et des méthodes statiques.

public interface Animal {


void seDeplacer();

// Méthode par défaut


default void dormir() {
[Link]("L’animal dort");
}

// Méthode statique
static void respirer() {
[Link]("Tous les animaux respirent");
}
}

Interfaces Fonctionnelles
Une interface fonctionnelle est une interface qui a une seule méthode
abstraite. Elle peut avoir plusieurs méthodes par défaut ou statiques. Les in-
terfaces fonctionnelles sont utilisées comme base pour les expressions lambda
en Java 8 et ultérieur.

@FunctionalInterface
public interface Calculateur {
int operation(int a, int b);
}

Les interfaces en Java offrent un moyen flexible de définir des contrats


pour les classes, tout en permettant une forme d’héritage multiple. Les in-
novations récentes comme les méthodes par défaut et les interfaces fonction-
nelles ont rendu les interfaces encore plus puissantes et polyvalentes.

35

Vous aimerez peut-être aussi