Les Fondamentaux de la Programmation Orientée Objet
Principes de base de la Programmation Orientée Objet (POO)
La programmation orientée objet est une méthode de programmation qui modélise le monde réel en utilisant des objets dans un modèle informatique. La POO est un paradigme qui transforme les entités du monde réel en objets au sein d'un programme, chacun possédant ses propres attributs et comportements. Ce paradigme met l'accent sur l'interaction entre objets pour réaliser les fonctionnalités du programme, plutôt que sur les opérations séquentielles de la programmation procédurale traditionnelle.
Caractéristiques de la pensée orientée objet
- Simplification des complexités
- Conformité aux habitudes de pensée humaine
- Passage d'exécutant à directeur
Les trois caractéristiques fondamentales de la POO :
- Encapsulation
- Héritage
- Polymorphisme
Les cinq principes de conception SOLID de la POO :
- Principe de responsabilité unique (SRP)
- Principe d'ouverture/fermeture (OCP)
- Prnicipe de substitution de Liskov (LSP)
- Principe d'inversion de dépendance (DIP)
- Principe de ségrégation des interfaces (ISP)
Classes et Objets
Une classe est un modèle qui définit les attributs et comportements communs à un ensemble d'objets. Elle peut être considérée comme un moule pour créer des objets similaires.
Dans le monde réel, pour décrire un ensemble d'entités :
Attributs : Ce sont les caractéristiques ou propriétés de l'entité.
Comportements : Ce sont les actions que l'entité peut accomplir.
Un objet est une instance concrète d'une classe. Un objet possède les attributs et comportements définis par sa classe.
Relation entre classes et objets
- Une classe est une description abstraite d'un ensemble d'entités
- Un objet est une concrétisation d'une classe
- Une classe sert de modèle pour créer des objets
Différence entre programmation procédurale et orientée objet
**Approche procédurale :**Décomposer le problème en séquence d'étapes à exécuter séquentiellement.
**Approche orientée objet :**Identifier les objets pertinents et leurs interactions pour résoudre le problème.
Exemple de classe et d'objet
// Définition d'une classe pour représenter un véhicule
class Vehicule {
String marque; // Attribut
String modele; // Attribut
int annee; // Attribut
// Méthode pour afficher les informations du véhicule
void afficherDetails() {
System.out.println("Marque: " + marque);
System.out.println("Modèle: " + modele);
System.out.println("Année: " + annee);
}
// Méthode pour simuler le démarrage
void demarrer() {
System.out.println("Le véhicule " + marque + " " + modele + " a démarré.");
}
}
// Création d'objets (instances de la classe Vehicule)
public class Main {
public static void main(String[] args) {
// Création du premier véhicule
Vehicule voiture1 = new Vehicule();
voiture1.marque = "Toyota";
voiture1.modele = "Corolla";
voiture1.annee = 2020;
// Création du deuxième véhicule
Vehicule voiture2 = new Vehicule();
voiture2.marque = "Honda";
voiture2.modele = "Civic";
voiture2.annee = 2022;
// Utilisation des méthodes des objets
voiture1.afficherDetails();
voiture1.demarrer();
voiture2.afficherDetails();
voiture2.demarrer();
}
}
Méthodes
Les méthodes sont des fonctions associées à une classe qui définissent le comportement des objets. Elles permettent d'interagir avec les attributs d'un objet et d'effectuer des opérations spécifiques.
Définition de méthodes
class CompteBancaire {
private String titulaire;
private double solde;
// Constructeur
public CompteBancaire(String titulaire, double soldeInitial) {
this.titulaire = titulaire;
this.solde = soldeInitial;
}
// Méthode pour déposer de l'argent
public void deposer(double montant) {
if (montant > 0) {
solde += montant;
System.out.println("Déposé: " + montant + "€");
} else {
System.out.println("Le montant doit être positif.");
}
}
// Méthode pour retirer de l'argent
public void retirer(double montant) {
if (montant > 0 && montant <= solde) {
solde -= montant;
System.out.println("Retiré: " + montant + "€");
} else {
System.out.println("Retrait impossible: montant invalide ou solde insuffisant.");
}
}
// Méthode pour obtenir le solde
public double obtenirSolde() {
return solde;
}
// Méthode pour afficher les informations du compte
public void afficherInfo() {
System.out.println("Titulaire: " + titulaire);
System.out.println("Solde: " + solde + "€");
}
}
// Utilisation des méthodes
public class Main {
public static void main(String[] args) {
CompteBancaire compte = new CompteBancaire("Jean Dupont", 1000.0);
compte.afficherInfo();
compte.deposer(500.0);
compte.retirer(200.0);
compte.afficherInfo();
}
}
Méthodes privées et publiques
Les méthodes privées (private) ne sont accessibles que depuis la classe elle-même, tandis que les méthodes publiques (public) sont accessibles depuis l'extérieur de la classe.
Mot-clé this
Le mot-clé this fait référence à l'objet actuel. Il est utilisé pour distinguer les attributs de la classe des paramètres de méthode portant le même nom.
class Etudiant {
private String nom;
private String prenom;
private int age;
public Etudiant(String nom, String prenom, int age) {
this.nom = nom; // 'this.nom' fait référence à l'attribut, 'nom' au paramètre
this.prenom = prenom;
this.age = age;
}
public void afficherIdentite() {
System.out.println("Nom: " + this.nom);
System.out.println("Prénom: " + this.prenom);
System.out.println("Âge: " + this.age);
}
}
Constructeurs
Les constructeurs sont des méthodes spéciales qui sont appelées lors de la création d'un objet. Ils sont utilisés pour initialiser les attributs de l'objet.
Constructeur par défaut
Si aucun constructeur n'est défini, Java fournit automatiquement un constructeur par défaut sans paramètres.
Constructeurs paramétrés
class Produit {
private String reference;
private String designation;
private double prix;
// Constructeur avec tous les paramètres
public Produit(String reference, String designation, double prix) {
this.reference = reference;
this.designation = designation;
this.prix = prix;
}
// Constructeur avec seulement la référence et la désignation
public Produit(String reference, String designation) {
this(reference, designation, 0.0); // Appel du constructeur principal
}
// Méthodes d'accès
public String getReference() {
return reference;
}
public String getDesignation() {
return designation;
}
public double getPrix() {
return prix;
}
public void setPrix(double prix) {
this.prix = prix;
}
public void afficher() {
System.out.println("Référence: " + reference);
System.out.println("Désignation: " + designation);
System.out.println("Prix: " + prix + "€");
}
}
// Utilisation des constructeurs
public class Main {
public static void main(String[] args) {
Produit produit1 = new Produit("REF001", "Ordinateur portable", 1200.0);
Produit produit2 = new Produit("REF002", "Souris sans fil");
produit1.afficher();
produit2.afficher();
produit2.setPrix(25.0);
produit2.afficher();
}
}
Surcharges de méthodes
La surcharge de méthodes permet de définir plusieurs méthodes avec le même nom mais avec des paramètres différents. Le compilateur détermine quelle méthode appeler en fonction des paramètres fournis.
class Calculatrice {
// Addition de deux entiers
public int additionner(int a, int b) {
return a + b;
}
// Addition de trois entiers
public int additionner(int a, int b, int c) {
return a + b + c;
}
// Addition de deux doubles
public double additionner(double a, double b) {
return a + b;
}
// Concaténation de deux chaînes
public String concatener(String str1, String str2) {
return str1 + str2;
}
// Concaténation de trois chaînes
public String concatener(String str1, String str2, String str3) {
return str1 + str2 + str3;
}
}
// Utilisation de la surcharge de méthodes
public class Main {
public static void main(String[] args) {
Calculatrice calc = new Calculatrice();
int somme1 = calc.additionner(5, 3);
int somme2 = calc.additionner(2, 4, 6);
double somme3 = calc.additionner(3.14, 2.86);
String texte1 = calc.concatener("Bonjour", " monde");
String texte2 = calc.concatener("Java", " est", " génial");
System.out.println("Somme 1: " + somme1);
System.out.println("Somme 2: " + somme2);
System.out.println("Somme 3: " + somme3);
System.out.println("Texte 1: " + texte1);
System.out.println("Texte 2: " + texte2);
}
}
Exercice : Création d'une classe avec constructeurs et méthodes surchargées
// Définir une classe "Livre" avec les attributs suivants :
// - titre (String)
// - auteur (String)
// - pages (int)
// - prix (double)
// Créer :
// 1. Un constructeur avec tous les paramètres
// 2. Un constructeur avec seulement le titre et l'auteur
// 3. Une méthode "afficherDetails()" pour afficher les informations du livre
// 4. Une méthode surchargée "appliquerReduction(double pourcentage)"
// qui applique une réduction en pourcentage au prix
// 5. Une méthode surchargée "appliquerReduction(double montantFixe, boolean enEuros)"
// qui applique une réduction fixe au prix
class Livre {
private String titre;
private String auteur;
private int pages;
private double prix;
// Constructeur avec tous les paramètres
public Livre(String titre, String auteur, int pages, double prix) {
this.titre = titre;
this.auteur = auteur;
this.pages = pages;
this.prix = prix;
}
// Constructeur avec seulement le titre et l'auteur
public Livre(String titre, String auteur) {
this(titre, auteur, 0, 0.0); // Appel du constructeur principal
}
// Méthode pour afficher les détails du livre
public void afficherDetails() {
System.out.println("Titre: " + titre);
System.out.println("Auteur: " + auteur);
System.out.println("Nombre de pages: " + pages);
System.out.println("Prix: " + prix + "€");
}
// Méthode surchargée pour appliquer une réduction en pourcentage
public void appliquerReduction(double pourcentage) {
if (pourcentage > 0 && pourcentage <= 100) {
prix = prix * (1 - pourcentage / 100);
System.out.println("Réduction de " + pourcentage + "% appliquée.");
} else {
System.out.println("Pourcentage de réduction invalide.");
}
}
// Méthode surchargée pour appliquer une réduction fixe
public void appliquerReduction(double montantFixe, boolean enEuros) {
if (montantFixe > 0) {
if (enEuros) {
prix = prix - montantFixe;
System.out.println("Réduction de " + montantFixe + "€ appliquée.");
} else {
prix = prix * (1 - montantFixe / 100);
System.out.println("Réduction de " + montantFixe + "% appliquée.");
}
if (prix < 0) {
prix = 0;
}
} else {
System.out.println("Montant de réduction invalide.");
}
}
// Getters
public String getTitre() {
return titre;
}
public String getAuteur() {
return auteur;
}
public int getPages() {
return pages;
}
public double getPrix() {
return prix;
}
}
// Utilisation de la classe Livre
public class Main {
public static void main(String[] args) {
Livre livre1 = new Livre("Apprendre Java", "Jean Martin", 350, 39.99);
Livre livre2 = new Livre("POO Avancée", "Sophie Bernard");
System.out.println("Livre 1:");
livre1.afficherDetails();
System.out.println("\nLivre 2:");
livre2.afficherDetails();
System.out.println("\nApplication des réductions:");
livre1.appliquerReduction(20); // Réduction de 20%
livre1.afficherDetails();
livre2.appliquerReduction(10.0, true); // Réduction de 10€
livre2.afficherDetails();
}
}
Résumé
- En POO, les classes et les objets ont une relation de modèle à instance
- Définir une classe revient à définir un type de données, dont les instances sont des variables de ce type
- Les champs définis dans une classe sont propres à chaque instance et ne s'interfèrent pas
- L'opérateur
newcrée de nouvelles instances, et des variables peuvent les référencer - L'accès aux champs d'une instance se fait par
nomVariable.nomChamp - Les variables qui référencent des instances sont des variables de référence
- Les méthodes permettent un accès sécurisé aux champs d'une instance
- Les méthodes sont un ensemble d'instructions pouvant exécuter n'importe quelle logique
- Une méthode rencontre une instruction
returnpour renvoyer une valeur,voidindique qu'aucune valeur n'est renvoyée - Le code externe utilise les méthodes publiques pour manipuler les instances, tandis que le code interne peut appeler des méthodes privées
- Les constructeurs sont utilisés pour initialiser les instances lors de leur création
- La surcharge de méthodes permet de définir plusieurs méthodes avec le même nom mais des paramètres différents