--- title: "mob2 - Cours 1 : CLOS" tags: mob2, cours --- {%hackmd theme-dark %} $$ \newcommand{\vt}[3]{ \begin{pmatrix} {#1} \\ {#2} \\ {#3} \end{pmatrix} } \newcommand{\limto}[1]{\xrightarrow[#1]{}} $$ # Modélisation objet 2 - Cours 1 : CLOS [`video`](url_video) [`cours`](url_cours) [`slides`](url_slides) ## Introduction générale Revu de tout ce qui est fait dans mob1 avec une nouvelle approche. Nous allons regarder comme ça fonctionne dans l'approche classique et l'adapter à l'approche dynamique ## Introduction CLOS = Common Lisp Object System Covarience et contravarience ne seront plusun problème. ### Origine Notion d'orienté objet vient avec Alan Kay et les langages de programmation Simula et Smalltalk dans les années 70 - 1987 : apparition de l'orienté objet dans lisp - Commité X3J13 fait la standardisation de Common Lisp : c'est une combinaison de tout les dialèctes de lisp (Flavors, Common Loops, Lucid) ### Caractéristiques Stratification en 3 couches : - API (syntaxique) : il s'agit de macro qui sont ensuite expend en fonctions (80% des fonctionalité du langage) fonctionnalité les plus courantes - API (fonctionnelle) : contient l'implémentation a proprement parler de l'orienté objet - Implémentation : Fonctions génériques (diff de envoi de messages): plus besoin d'implémenter les méthodes dans la classe elle-même Héritage multiple : - System de précédence de classe linéarisé (On peut définir la priorité des classes parents) Combinaison de méthodes : - Invocation simple/ multiple (on pourrait utiliser plusieurs méthodes avec la même signature compiner les résultats et en retourner la valeur combiné) - Combinaison déjà par défaut mais aussi programmable. - En approche classique il faudrait changer la sémantique du langages ou alors simuler avec des disgne paterne. Order superieur (Méta Object Protocol MOP): - Principe : couche orienté objet est implémenté en orienté objet méta-circularité - Chaque concepte est orienté objet (classe est une instance d'une classe = méta-classe) - On adapte les langage à nos besoins Typage dynamique: Pas d'encapsulation ni de protection: - pas de private, public, protected, friend ## Classs et Objets Classe = Extension de l'enregistrement ### Casses et objets defclass = (macro) déclarer une classe une classe a des slote les classes ont une définition fonctionnelle - Cycle de vie : dynamique fabriqué au run-time (à la fois un type et un objet) - typage dynamque : les parametre de la classe pas de type précis au départ - Méthodes : ne sont pas délaré dans la classe elle-même. - Pas de protection - Pas de classe abstraite, final #### Instansiation (make-instance 'human) ' permet de ne pas évaluer human Remarques : - Instanciation fonctionnelle ce n'est pas un constructeur - Fonction commune à toutes les classes - Il y a un garbedge collector Problème : initialisation des slots ##### Initialisation Dans la déclaration de la classe(name :initarg :name) initinlisation (make-instance 'human :name "Alex Terieur") Problème : initialisation par défaut si on ne donne pas l'info pour name (name :initarg :nale :iniform "TOTO") permet de donner une valeur par défaut si pas de valeur donnée à la création Création d'une fonction constructeur spéciale pour chaque classe est conventionnel Privilégier les keywords aux paramètres optionnels ### Portée et acccessibilité de l'information Remarques : - Par défaut : :allocation :instance - Pas d'accès standard aux slots partagés à travers les classes - Pas d'équivalent direct des méthodes de classe (slot-value alain 'birthyear) alain c'est l'objet birthyear c'est le paramètre Remarques : - Accès fonctionnel (pas syntaxique) - Fonction commune à toutes les classes - Pas de mécanisme de protection On passe par des accesseur pour ne pas avoir à connaire le nom du paramètre (du slot) (name : intarg :name :reader name :writer rename) permet de lire et réécrire le champ name (size :initarg :size :accessor size) permet de lire (size alain) et écrire (setf (size alain) 1.78) Remarque : - Génération automatique de fonctions avec :reader et :writer ### Intégration Classes / Types Forte intégration type/classe: - Hiérarchie unique : classe racine t (classe-of) - Correspondance classe / type (type-of typep) - Correspondance type naif / classe ## Héritage ### Rappels Copier-Coller c'est très mal Agrégation : relation "ensemble / partie" Composition : agrégation plus forte Héritage : forme d'inclusion implicite (defclass employee (human) (company salary)) employee hérite de human et héritage multiple possible par ordre décroissant de gauche à droite Héritage implicite : hiérarchie de classe unique. toute classe hérite de user-class et tout instance hérite de standard-object Héritage des slots : - slot unique donc déclarer un humain nommée foo et un employé nommé foo ça sera le même objet Héritage des options : - Il y a une combinaison des informations - initargs sont accumulés - initforms : celui choisi est celui le plus proche de la classe ensuite on remonte les différents héritages Héritage des méthodes : - Ce comporte de la même manière que classiquement Héritage multiple : possible ### Modèle d'héritage ### Problèmes liée à l'héritage Pésistants : - Ne pas confondre héritage et instanciation - Ambivalence de l'héritage (intérface / implémentation) Alternatives : - Héritage par restriction / programmation différentielle - Héritage multiple / diament : fusion des définitions / packages ## Polymorphisme ### Rappels #### Polymorphisme statique - Surcharge : plusieurs fonction avec le même nom mais pas la même signature - - n'a pas de sens dans les langages dynamique car on ne donne pas de type aux arguments - - Cardinalité : trop ambigu / compliqué - - Remplacée par une sémantique d'appel plus riche - Masquage : inter-classe méthodes qui ont le même nom dans une classe et ça super-classe - - Spécifique aux méthodes membres - - Aucun sens avec des fonctions génériques car les méthodes ne sont pas défini dans la classe #### Polymorphisme dynamique - Ré-écriture - - Fonctions génériques - - Méthodes ### Fonctions Génériques et Méthodes (defgeneric translate (object x &optional y)) defgeneric = macro Remarques : - Définition fonctionnelle : pas de syntaxe spécifique - Cycle devie dynamique - Typage dynamique - Interface uniquement - Déclaration optionnelle - Les accesseurs sont des fonctions génériques (defmethod translate ((circle circle) x &optional (y 0)) (translate (centre circle)x y)) (circle circle) = variable puis classe defmethod = macro Remarques : - Définition fonctionnelle - Cycle de vie dynamique (méta-object) - typage dynamique - methode = implémentation particulière de la fonction générique - Spécialisation sur les arguments obligatoires - méthode par défaut = non spécialisée si la classe n'est pas spécifié - méthode non exécutables et anonymes : on appele une fonction qui va executer la méthode call-next-method = appeler la fonction de la classe superieur ### Relation (sous-)class / (sous-)type #### Covariance et contravariance