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