# Programmation orientée objet > [!info]- Parfois abbrégée **OOP** ou encore **POO** > > >![[caca.gif|320x240]] > Non, pas celle-là. --- ## Définition La [[Glossaire général#Paradigme de programmation orientée objet|programmation orientée objet]] (abrégé OOP ou POO en français) est un [[Glossaire général#Paradigme de programmation|paradigme de programmation]]. Il définit un [[Glossaire général#Programme informatique|programme informatique]] comme constitué **d'[[Glossaire général#Objet|objets]]** qui **interagissent entre eux** Le paradigme de programmation orienté-objet est très fortement lié à la **[[Glossaire général#Modélisation objet|modélisation objet]]**. --- ## Objet Les **objets** sont des **[[Glossaire général#Structure de données|structures de données]]** qui *[[Glossaire général#Encapsuler (programmation)|encapsulent]]* des **données ([[Glossaire général#Attribut (d’une classe)|attributs]])** et des **routines ([[Glossaire général#Méthode|méthodes]])** définissant leur comportement. Les valeurs que prennent l’ensemble des attributs d’un objet est [[Glossaire général#État d’un objet|l’état]] de cet objet. ![[dev.java_oop_schema.png|453x272]] Source : https://dev.java/learn/oop/ --- ## Classe Certains langages de POO comme java s'appuie sur un système de [[Glossaire général#Classe|classe]] pour organiser le code et servir de patron pour la création d'objets. Il faut un peu voir les classes comme des recettes de cuisine pour objets. ![[class-instance-objet.gif|360x270]] --- ## Motivations - **Modéliser une simplification du monde réel** à l'aide de concepts qui en sont proches pour pouvoir le traduire en programme informatique - Faciliter la communication avec des parties prenantes différentes autour de représentations plus proches de concepts de la réalité --- ## Principes Concernant la relation des objets entre eux : - **Ignorance** : "Don't know" (je ne veux pas savoir) - **Apathie** : "Don't care" (je m'en fiche) - **Égoïsme** : "Let's talk about what **I** want" (et si on parlait de ce que **JE** veux ?) --- ## 4 Piliers de la POO - Abstraction - Encapsulation - Polymorphismes - Héritages Certains parlent de "4 pilliers de la POO". > [!important]- Plusieurs saveurs de programmation orientée objet > Les propriétés suivantes sont généralement considérées comme les **4 piliers** du paradigme de programmation orientée objet. > > Leur signification dans ce cours est à prendre **dans le contexte de la programmation orientée objet** en **Java**. > > Dans d'autres langages et paradigmes, elles peuvent avoir des significations, nuances ou des implémentations un peu différentes ## Abstraction > The essence of abstraction is preserving **information that is relevant** in a given **context**, and forgetting **information that is irrelevant** in that context. – [John V. Guttag](https://en.wikipedia.org/wiki/John_Guttag "John Guttag") <!-- Formuler le **concept généralisé** d'une **propriété commune** applicables à des entités ou concepts variés sans considérer les différences des instances de ceux-ci. Autrement dit, **masquer les détails conceptuels ** dont on n’a pas besoin dans un certain contexte. --> - **Dissimuler** des **détails de l'implémentation interne** et ne présenter que des **fonctionnalités essentielles** à l'utilisateur. - Se concentrer sur **ce que fait** un objet ou une méthode plutôt que comment il le fait. - Cacher les **détails complexes** et ne montrer que des **caractéristiques essentielles**. > [!tip] En abstrayant une fonctionnalité, les changements dans l'implémentation n'affectent pas le code qui dépend de l'abstraction. [[Glossaire général#Abstraire|Abstraire]] consiste à réduire le code d'un niveau de détail. En bref, appliquer les principes d'ignorance, d'apathie et d'égoïsme. > [!example] Abstraction et voiture > Je n'ai pas besoin de savoir comment fonctionne une voiture pour la conduire. Pratique ! --- ### Motivations L'abstraction est l'utilisation de choses simples pour représenter la complexité. - découper des **problèmes complexes** en **sous-problèmes plus simples.** - pouvoir **se concentrer sur un problème à la fois**. - pouvoir modifier/substituer des [[Glossaire général#Couche d’abstraction|couches d'abstraction]] inférieures sans **sans changer les couches supérieures** --- ### Couches d'abstraction Toute couche logicielle qui cache aux développeur-euses les détails d'implémentation de la couche inférieure. Exercice : pouvez-vous donner des couches d'abstraction que vous connaissez ? > [!example]- Exemples de couches d'abstraction > - Je peux installer le même système d'exploitation sur 2 ordinateurs différents. > - La machine virtuelle Java est une couche d'abstraction entre le code java compilé et la machine sur laquelle il est exécuté > - Une API HTTP est une couche d'abstraction qui cache le fonctionnement du serveur qui l'expose > - Le JDK est une couche d'abstraction qui s'appuie sur la couche d'abstraction du système d'exploitation pour lire / écrire des fichiers via `java.util.File` , lui-même s'appuyant sur un driver, une autre couche d'abstraction entre le système d'exploitation et le disque-dur (matériel) ### Exo : quelles abstractions ? > Quelles abstractions voyez-vous dans cette photo? > Quelles couches d’abstraction sont presentes? ![[2CC8F7E9-B467-4E16-9D3E-421C204E25AA.jpeg|321x240]] --- ### Mécanismes d'abstraction en Java - Classes abstraites (abstraction partielle) - Interface (abstraction complète) --- ## Encapsulation L’encapsulation est la propriété dominante et la plus importante du paradigme orienté objet. Elle consiste à présenter **une [[Glossaire général#Interface (programmation)|interface]] publique** cohérente **indépendante de ses détails d'[[Glossaire général#Implémentation|implémentation]]** internes (privés). > [!success] Penser encapsulation comme "mettre dans une capsule" > Créer une délimitation, une barrière, autour de quelque-chose qu'on veut protéger de l'extérieur. > > ![[fallout-shelter-bottle-cappy.png|240x268]] > Source : [@Bethesda_fr](https://x.com/Bethesda_fr/status/771260587942617089) --- > [!tip]- L'encapsulation n'est pas une propriété exclusive de la POO > Elle peut s'exprimer par des mécanismes différents selon le paradigme ou le langage; > > Par exemple, en C, une forme d'encapsulation peut être mise en oeuvre par la séparation des fichiers d'entête (`.h`) de ceux de l'implémentation (`.c`). --- ### Motivations - Modifier les structures de données internes sans modifier l’**interface publique** ni le comportement d'une abstraction - Masquage des données : maintenir les détails internes d'un objet cachés du monde extérieur - Ajouter aisément des règles de validation et de cohérence des **invariants** - Voir aussi : [[Parse don’t validate]] - Éviter l’[[Glossaire général#Antipattern|antipattern]] du [plat de spaghetti](https://fr.wikipedia.org/wiki/Programmation_spaghetti "Programmation spaghetti") qui ne permet pas de déterminer le qui, le quoi et le comment d’une modification de données[^2] - Augmenter [[Glossaire général#Cohésion|la cohésion]] en groupant les données et les traitement poches les uns des autres - Réduire [[Glossaire général#Couplage|le couplage]] pour s'assurer que les seulement certaines parties des données sont utilisés par des traitements associés - Offrir une [[Glossaire général#Interface (programmation)|interface]] orientée **services** et **responsabilités** et la considérer comme une **"boîte noire"** --- ### Encapsulation en POO Dans les langages orientés objet, on considère souvent l'encapsulation en 2 composantes: - Un mécanisme de langage pour **restreindre l'accès direct** à certains des composants de l'objet. - Une construction de langage qui facilite **le regroupement des données** avec **les routines** qui les manipulent. > [!info] Égoïsme et apathie appliqués > Ce qui m'intéresse quand j'appelle un objet c'est **le service** qu'il me rend. Pas comment il me le rend. --- ### Encapsulation en Java En java, l'encapsulation peut être mise en œuvre via différents mécanismes: - [[Encapsulation en Java#Mécanismes de groupement d’informations en Java|mécanismes de groupement d'informations]] - [[Encapsulation en Java#Modificateurs de visibilité|modificateurs de visibilité]] - mécanismes d'héritage Nous y reviendrons dans un module dédié. > [!tip]- La présence de bloc `{ ... }` est souvent signe d'une forme d'encapsulation > [!example] Encapsulation et voiture > - L'interface publique : feux de freinage, ou clignotants pour indiquer les virages ou dangers potentiels > - Interface privée : sous le capot, type de carburant, température du moteur, beaucoup de données qui pourraient perturber les autres conducteurs ![[2CC8F7E9-B467-4E16-9D3E-421C204E25AA.jpeg|321x240]] --- ## Polymorphisme Le [[Glossaire général#Polymorphisme|polymorphisme]] est **une expression** de l'encapsulation. Le polymorphisme veut dire que le même service, aussi appelé opération ou méthode, peut avoir un comportement différent selon les situations. Le polymorphisme est **l’application de l’encapsulation** au regard d’une **[[Glossaire général#Interface (programmation)|interface/protocole]]** ou d'une **hiérarchie de classe**. Dans le cas du polymorphisme par [[Glossaire général#Sous typage|sous-typage]], il permet de fournir **une interface unique** à des entités **pouvant avoir différents [[Glossaire général#Type|types]]** Différentes modalités de polymorphisme - polymorphisme ad hoc en Java - polymorphisme paramétré - polymorphisme par sous-typage - Héritage d'interface - Héritage d'implémentation Voir aussi : [[Polymorphismes en Java]] > [!example] Polymorphisme et voiture > Je peux conduire des voitures différentes pourvu qu'elles aient un volant et des pédales. ![[2CC8F7E9-B467-4E16-9D3E-421C204E25AA.jpeg|321x240]] --- ### Motivations Utiliser des objets de [[Glossaire général#Type|types]] différents là où est attendu un objet d'un certain type. --- ## Héritage En programmation orientée objet, la notion [[Glossaire général#Héritage|d’héritage]] recouvre le plus souvent deux aspects distincts : - La réutilisation de code ([[Glossaire général#Héritage d’implémentation|héritage d’implémentation]]) - Le [[Glossaire général#Sous typage|sous‑typage]] (voir Polymorphisme) --- ### Héritage d'implémentation L'héritage définit des **relations hiérarchiques** entre les classes, de sorte que les **attributs** et **méthodes communs** peuvent être **réutilisés**. > [!example]- Exemple de hiérarchie de classes : Listes > ![[ex-heritage-implementation-listes.png|319x221]] En définissant des attributs et des comportements de base dans une classe, il est possible de créer des classes **dérivées** qui **étendent** la fonctionnalité de la classe principale et ajoutent des attributs et des comportements supplémentaires. L’héritage représente un concept de **généralisation/spécialisation**. Une classe mère est la généralisation de ses classes enfants, et inversement, les classes enfants sont des spécialisations de la classe mère. --- ### Motivations On utilise l’héritage principalement pour partager du code entre différents types d’objets. - Plus particulièrement pour les cas suivants: - On souhaite **factoriser**, c’est-à-dire regrouper des attributs et/ou comportements entre plusieurs types d’objets sans avoir à les réécrire. - On veut **étendre** une classe en lui ajoutant des caractéristiques comme des données ou des comportements. - On veut pouvoir manipuler des objets de classes différentes de la même manière. --- > [!warning] Attention à la taxe de l’heritage ! > Vous vouliez une banane, mais ce que vous avez obtenu, c’est un gorille qui tenait la banane et toute la jungle. > — Joe Armstrong --- # À suivre [[Java - Essentiels]]