Programmation orientée objet
Ce document traite des concepts fondamentaux de la programmation orientée objet, notamment l'héritage, la redéfinition des méthodes et le polymorphisme, avec des exemples en Java. Il s'adresse aux étudiants en informatique souhaitant comprendre comment structurer et réutiliser du code efficacement grâce à ces mécanismes.
D'après le document Programmation orientée objet
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Héritage, Polymorphisme, Programmation · PDF · 6 pages
Afficher l'aperçu du document
Ce document traite des concepts fondamentaux de la programmation orientée objet, notamment l'héritage, la redéfinition des méthodes et le polymorphisme, avec des exemples en Java. Il s'adresse aux étudiants en informatique souhaitant comprendre comment structurer et réutiliser du code efficacement grâce à ces mécanismes.
Héritage
L'héritage est un mécanisme qui facilite la réutilisation du code et la gestion de son évolution. Il permet d'implémenter le principe d'abstraction en factorisant les propriétés et opérations communes à plusieurs objets. Une classe générale définit un ensemble d'attributs partagés par d'autres classes dites sous-classes ou classes descendantes.
Grâce à l'héritage, les objets d'une sous-classe ont accès aux données et méthodes de la classe parente et peuvent les étendre. Les sous-classes peuvent redéfinir les variables et méthodes héritées. Pour les variables, il suffit de les redéclarer avec le même nom mais un type différent. Pour les méthodes, la redéfinition se fait avec le même nom, les mêmes types et le même nombre d'arguments. Sinon, il s'agit d'une surcharge.
L'héritage successif permet de créer une hiérarchie de classes composée de super-classes et sous-classes.
- Une classe peut avoir plusieurs sous-classes.
- Une classe ne peut avoir qu'une seule classe mère (pas d'héritage multiple en Java).
- La classe
Objectest la classe mère de toutes les classes en Java. Toutes les variables et méthodes contenues dansObjectsont accessibles par héritage successif.
Syntaxe :
public class NomClasse1 extends NomClasse2 {
...
}
Exemple :
public class Etudiant1et2 extends Etudiant {
private double Note1;
private double Note2;
...
}
Dans cet exemple, la classe Etudiant1et2 hérite des attributs et méthodes de la classe Etudiant. Un objet de type Etudiant1et2 possède, en plus des attributs Note1 et Note2, les attributs hérités de Etudiant comme Nom, Prenom, Adresse et CIN. Ces derniers étant déclarés privés, ils ne sont pas accessibles directement dans la sous-classe ; il faut utiliser les getters et setters. En revanche, Note1 et Note2 sont accessibles directement.
Remarque : Les attributs hérités déclarés public ou protected peuvent être utilisés directement dans la sous-classe.
Redéfinition
La redéfinition consiste à réimplémenter dans une classe descendante une méthode définie dans la classe mère. Généralement, la redéfinition étend le comportement de la méthode mère. On commence souvent par appeler la méthode de la classe mère à l'aide du mot-clé super.NomDeLaMethode(param1, param2,...). Pour les constructeurs, on utilise super(param1, param2,...).
Exemple : redéfinition de deux constructeurs et de la méthode afficherEtudiant()
public class Etudiant1et2 extends Etudiant {
private double Note1;
private double Note2;
public Etudiant1et2(String Nom, String Prenom, String Adresse, String CIN, double note1, double note2) {
super(Nom, Prenom, Adresse, CIN);
this.Note1 = note1;
this.Note2 = note2;
}
public Etudiant1et2() {
super();
}
public void afficherEtudiant() {
super.afficherEtudiant();
System.out.println("La note1 de l’étudiant est " + Note1);
System.out.println("La note2 de l’étudiant est " + Note2);
}
}
Remarque : Si la méthode redéfinie dans la sous-classe a un nombre de paramètres ou un type de retour différent, il s'agit d'une surcharge et non d'une redéfinition.
Polymorphisme
Le polymorphisme permet de manipuler des objets sans connaître précisément leur type, en se basant sur la relation d'héritage. Un objet peut être déclaré avec un type générique (super-classe) puis instancié avec une classe descendante.
En Java, le polymorphisme se traduit par :
- La compatibilité entre un type dérivé et un type ascendant.
- La liaison dynamique des méthodes, permettant d'obtenir un comportement adapté à chaque type d'objet sans tester explicitement sa nature.
Exemple 1 : utilisation du polymorphisme avec un tableau d'étudiants
public class Principale {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
Etudiant[] Tab = new Etudiant[2]; // Déclaration d’un tableau d’étudiants
int niveau;
for (int i = 0; i < 2; i++) {
System.out.println("Taper le niveau d'étude de l'étudiant 1, 2 ou 3");
niveau = sc.nextInt();
if (niveau == 1 || niveau == 2) {
Tab[i] = new Etudiant1et2();
Tab[i].saisir();
} else if (niveau == 3) {
Tab[i] = new Etudiant3();
Tab[i].saisir();
} else {
System.out.println("Niveau incorrect");
}
}
for (int i = 0; i < 2; i++) {
Tab[i].afficherEtudiant();
}
}
}
Dans cet exemple, la méthode saisir() et afficherEtudiant() sont appelées sur des objets du tableau Tab dont le type réel est soit Etudiant1et2 soit Etudiant3. Le compilateur utilise la liaison dynamique pour exécuter la méthode correspondant au type réel de l'objet.
Remarques :
- Si une méthode n'est définie que dans la sous-classe et pas dans la classe mère, le polymorphisme ne peut pas s'appliquer directement.
- Ce problème peut être contourné par un transtypage (casting).
Exemple 2 : utilisation du casting pour appeler une méthode spécifique
public class Principale {
public static void main(String args[]) {
// ... initialisation de Tab ...
for (int i = 0; i < 2; i++) {
Tab[i].afficherEtudiant(); // Polymorphisme
if (Tab[i] instanceof Etudiant3) {
((Etudiant3) Tab[i]).afficherMoyenne();
}
if (Tab[i] instanceof Etudiant1et2) {
((Etudiant1et2) Tab[i]).afficherMoyenne();
}
}
}
}
Exercice : compter le nombre d'étudiants par type
À partir de l'exemple précédent, comment connaître le nombre total d'étudiants, le nombre d'Etudiant1et2 et le nombre d'Etudiant3 ?
Correction :
Méthode 1 : utilisation de l'opérateur instanceof
public class Principale {
public static void main(String args[]) {
// ... initialisation de Tab ...
int etud3 = 0;
int etud1et2 = 0;
for (int i = 0; i < 2; i++) {
if (Tab[i] instanceof Etudiant3) {
etud3++;
}
if (Tab[i] instanceof Etudiant1et2) {
etud1et2++;
}
Tab[i].afficherEtudiant();
}
System.out.println("Le nombre d'étudiants 1er et 2eme est : " + etud1et2);
System.out.println("Le nombre d'étudiants 3eme est : " + etud3);
}
}
Méthode 2 : utilisation d'attributs statiques dans les classes
On peut ajouter un compteur statique dans chaque classe descendante pour compter le nombre d'instances créées.
public class Etudiant1et2 extends Etudiant {
private double Note1;
private double Note2;
public static int compteurEtudiant1et2 = 0;
public Etudiant1et2(String Nom, String Prenom, String Adresse, String CIN, double note1, double note2) {
super(Nom, Prenom, Adresse, CIN);
this.Note1 = note1;
this.Note2 = note2;
compteurEtudiant1et2++;
}
public Etudiant1et2() {
super();
compteurEtudiant1et2++;
}
}
public class Etudiant3 extends Etudiant {
private double Note1;
private double NotePFE;
public static int compteurEtudiant3 = 0;
public Etudiant3(String Nom, String Prenom, String Adresse, String CIN, double note1, double notePFE) {
super(Nom, Prenom, Adresse, CIN);
this.Note1 = note1;
this.NotePFE = notePFE;
compteurEtudiant3++;
}
public Etudiant3() {
super();
compteurEtudiant3++;
}
}
public class Principale {
public static void main(String args[]) {
// ... création des objets ...
System.out.println("Le nombre d'étudiants 1er et 2eme est : " + Etudiant1et2.compteurEtudiant1et2);
System.out.println("Le nombre d'étudiants 3eme est : " + Etudiant3.compteurEtudiant3);
}
}
Glossaire des termes clés
- Héritage : mécanisme permettant à une classe d'acquérir les propriétés et méthodes d'une autre classe.
- Classe mère (super-classe) : classe dont héritent d'autres classes.
- Classe fille (sous-classe) : classe qui hérite d'une autre classe.
- Redéfinition : réimplémentation d'une méthode héritée dans une sous-classe avec la même signature.
- Surcharge : définition d'une méthode avec le même nom mais une signature différente (nombre/type d'arguments).
- Polymorphisme : capacité à utiliser un objet de différentes classes dérivées via une référence de la super-classe.
- Liaison dynamique : mécanisme qui permet d'appeler la méthode appropriée selon le type réel de l'objet à l'exécution.
- Opérateur instanceof : opérateur permettant de tester si un objet est une instance d'une classe donnée.
- Casting : conversion explicite d'un objet d'un type générique vers un type plus spécifique.
- Attribut statique : variable partagée par toutes les instances d'une classe, souvent utilisée pour compter les objets créés.
Points clés à retenir
- L'héritage permet la réutilisation du code et la création de hiérarchies de classes.
- Les méthodes héritées peuvent être redéfinies dans les sous-classes pour étendre ou modifier leur comportement.
- Le polymorphisme permet d'utiliser des références de type général pour manipuler des objets de types spécifiques.
- La liaison dynamique garantit que la méthode appelée correspond au type réel de l'objet.
- Si une méthode n'existe pas dans la super-classe, il faut utiliser le casting pour accéder aux méthodes spécifiques des sous-classes.
- On peut compter les instances de chaque sous-classe via l'opérateur
instanceofou des compteurs statiques.
Commentaires
Aucun commentaire pour le moment. Posez la première question.