====== Classes - Programmation orientée objet (POO) ======
{{nsi:langages:lisp_logo.png?nolink&50 |Lisp}}
{{ nsi:langages:java_logo.png?nolink&50|Java}}
{{ :nsi:terminales:classes:classes.fiche.pdf |Fiche à imprimer}}
Apparu en 1960 avec LISP. Très répandu aujourd'hui. En Java, //presque// tout est objet.
===== Paradigme de programmation =====
== Programmation procédurale ==
Le programme est découpé en fonctions ou procédures -- //fonctions qui ne retournent rien// -- réalisant chacune un morceau de l'ensemble.
Les fonctions sont alors séparées des données traitées, elles sont toutes au même niveau, et les données subissent passivement.
== Programmation orientée objet ==
Les données sont structurées en objets qui définissent des méthodes -- //fonction d'un objet// -- pouvant leur être appliquées, et des attributs.
Les objets sont responsables de l'exécution des fonctions, ils ne sont plus passifs. Les fonctions sont organisées selon les objets auxquelles elles appartiennent.
Dans l'[[classes_exo_preparation|exercice]] on rencontre les problèmes :
* Pas de façon simple pour regrouper toutes les données concernant le triangle,
* pas de façon simple de savoir qu'une variable contient un triangle, et un triangle bien formé,
* multiplication de fonctions en vrac.
Les classes vont permettre de simplifier ces problèmes :
* La classe définit un modèle qui définit la façon de créer et d'utiliser des objets. Une classe ''Triangle'' permettra de définir exactement les données contenues dans un objet de ce type.
* Dès lors qu'un objet est de type ''Triangle'', on est certain qu'il respecte les contraintes qu'on a fixé dans la classe.
* Chaque classe définit ses propres méthodes de sorte que le code est mieux organisé. ''Triangle'' possède sa méthode ''aire'' qui ne pourra être confondu avec la méthode ''aire'' de ''Parallelogramme''.
===== Notion de classe =====
Un objet est défini par une **classe**. La classe est la notice qui détaille comme on **fabrique** l'objet et comment on l'**utilise**.
* La classe définit des **méthodes** (fonctions dans une classe) qui définissent le fonctionnement de la classe et son interface -- comment l'extérieur peut agir sur un objet.
* Elle a aussi des **attributs**, c'est à dire des données qui la caractérisent. Par exemple, objet //Humain// aurait les attributs //genre//, //age//...
Cela rappelle la définition abstraite des structures de données -- [[.structures:liste_abstraite|Listes]], [[.structures:pile_abstraite|Piles]] et [[.structures:file_abstraite|Files]] -- consistant à préciser toutes les propriétés désirées. Une classe est une implémentation qui énonce naturellement les propriétés désirées.
===== Définir une classe =====
==== Donner un nom ====
Une classe est identifiée par un nom. L'usage est d'utiliser la casse du chameau, [[https://fr.wikipedia.org/wiki/Camel_case|UpperCamelCase]].
Par exemple : ''Triangle'', ''TriangleIsocele'', ''Losange'', ''PolygoneRegulier''
==== Identifier les attributs ====
Qu'est ce qui définit un objet ?
Un triangle sera défini par ses 3 sommets. Ses attributs seront donc ces sommets. Mais sous quelle forme ?
* 6 variables pour les 3 paires de coordonnées ?
* un tableau contenant les 3 paires de coordonnées ?
* 3 objets ''Point'' que l'on devrait aussi définir ?
On a le choix.
==== Définir l'interface =====
Comment agit on sur un objet depuis l'extérieur ?
On doit bien sûr pouvoir le créer. Un objet aura toujours un **constructeur** qui est une méthode spéciale permettant de le créer -- notamment de réserver l'espace nécessaire en mémoire -- puis de l'initialiser.
Et puis par exemple, pour un ''Triangle'', on voudra calculer son aire, son périmètre... Ce sont autant de méthodes que la classe devra posséder.
==== Choisir la visibilité ====
En général, les classes permettent de régler finement les éléments d'un objet qui sont accessibles depuis l'extérieur et ceux qui ne le sont pas. Mais ce n'est pas le cas en Python : En Python, tout est visible. Nous parlerons donc de visibilité au cours des exercices mais sans trop insister.
Un élément accessible est dit **public**, s'il est inaccessible, il est dit **privé**.
==== Diagramme UML ====
{{nsi:langages:uml_logo.png?nolink&100 |}}
Pour aider au développement et au travail de groupe, les informaticiens ont recours à différents types de diagrammes dont le but est de communiquer rapidement les choix effectués. Le UML -- Unified Modeling Language -- en fait partie.
C'est un vaste domaine, nous allons rester simples.
> Les + signifient "public". Pour "privé", on aurait mis un -
^ Triangle ^
|**Attributs**|
| + réel : x1 |
| + réel : y1 |
| + réel : x2 |
| + réel : y2 |
| + rée l: x3 |
| + réel : y3 |
| + texte : nom |
|**Méthodes**|
| + construire(réels: x1, y1, x2, y2, x3, y3, texte:nom) |
| + réel : aire() |
| + réel : périmètre() |
//diagramme UML//
Dans un programme complexe, le diagramme UML permettra d'indiquer les **dépendances** entre les différentes classes.
==== Dépendance ====
Supposons que l'on crée une classe ''Point'' pour gérer les points et qu'alors ''Triangle'' utilise cette classe. On peut faire apparaître clairement la dépendance sur le diagramme UML.
{{ nsi:terminales:classes:umltrianglepoint.png?nolink&400 |}}