La programmation par objets Principes et concepts Etude de Smalltalk
Smalltalk-80 – Vue générale Historique Concepts Génie logiciel Réflexivité Parallélisme MVC Langage Smalltalk-80 Environnement de programmation Java a été influencé par C / C++ pour la syntaxe Smalltalk pour plusieurs concepts et la librairie
Historique ST-72 ST-76 ST-80 LIBERTÉ !!! Simula 67 Lisp Logo FLEX objets classes héritage Lisp interprète environnement interactif Logo Syntaxe Tortue (environnement graphique) FLEX envois de messages ST-72 ST-76 ST-80 LIBERTÉ !!! Langage de programmation Environnement graphique Système d’exploitation Environnement de programmation interactif
Axiomes Tout entité du langage est un objet (uniformité) Tout objet est instance d’une classe (uniformité) L’héritage est simple La seule structure de contrôle est l’envoi de messages (uniformité) Tout est accessible / modifiable par l’usager
Concepts primitifs Objet Message Classe (héritage) Instance Méthode
Activation du comportement OBJET Objet = < variables d’instance, méthodes > nommées indexées Support de la modularité Le fonctionnement de tout objet est indépendant des détails internes des autres objets Activation du comportement Transmission de messages Séparation Le seul moyen pour assurer avantages Méthode employée par le récepteur pour la réalisation de cette intention Intention de l’émetteur Renforcer l’utilisation d’abstractions Uniformité MODULARITÉ
MESSAGES Message == OBJET (respect de A1) sélecteur arguments Exemple 1 1 + 2 sémantique 1 Sélecteur : + Argument : 2 Structures de contrôle traditionnelle messages Exemple2 : conditionnelle x = y ifTrue: [ egalite <- ‘egal’ ] ifFalse: [ egalite <- ‘distinct’] sélecteur arguments Bloc : évaluation différée Objets + Envois de messages Tout ce qu’il faut pour construire l’environnement de programmation
CLASSES Une vision platonique des objects abstraction Classification d’objets similaires Factorisation de descriptions des objets individuels
Factorisation des descriptions Structure Comportements Variables d’instance (état) Dictionnaire des méthodes objet objet Sélecteur Paramètres Séquence d’expressions indexées (Array) nommées Variables temporaires
Classe = objet + capacité de générer des objets instances x = 1 y = 2 i n t x y y: x = 3 y = 4 i n t x y y: FACTORISATION Structure : { x, y } Comportements : { x, y, y:, init } Classe Point
INSTANCIATION Création d’une instance Interprétation des messages Transmission de message Point new (uniformité) Interprétation des messages Lien d’instanciation Ma classe connaît mon comportement
classVariables = Dessin pool : ICONES { (Smiley, ), (Slomo, ;-) } Tortue class initialize [[true] whileTrue: [ Time avantMidi ifTrue:[ Dessin := Slomo] ifFalse: [ Dessin := Smiley] ]] fork classVariables = Dessin Point class newInit ^self new initialize Hérite de Instance de Instance de i-v = { x, y } Point initialize x := 0. y := 0. y: unEntier y := unEntier. y ^y Hérite de i-v = { direction } Tortue initialize super initialize. direction := 270 avance: n self av: (Dessin = Slomo ifTrue: [n/2] ifFalse: [n]) av: n n>0 ifTrue: [self y: self y + 1. self av: n – 1.] newInit Création d’une instance : Tortue newInit quelle méthode initialize sera utilisée? initialize de Tortue : masquage avec réutilisation différence entre self et super Transmission d’un message à une instance : Tortue newInit avance: 10 variable d’instance et variable de classe méthode d’instance et méthode de classe x=0 y=0 direction = 270 Instance de avance: 10
Réflexivité structurelle Tout est objet (A1) Une classe est un objet Tout objet est instance d’une classe (A2) Une classe est instance d’une classe sa métaclasse Méthodes de classes (comportement de la classe) Ex: new, subclass: anonyme créée automatiquement mais, ClassTalk Architecture réflexive tout est disponible on peut modifier le fonctionnement de l’instanciation 1er type de hiérarchie : graphe d’instanciation
classVariables = Dessin pool : ICONES { (Smiley, ), (Slomo, ;-) } Tortue class initialize [[true] whileTrue: [ Time avantMidi ifTrue:[ Dessin := Slomo] ifFalse: [ Dessin := Smiley] ]] fork classVariables = Dessin Point class newInit ^self new initialize Hérite de Instance de Instance de i-v = { x, y } Point initialize x := 0. y := 0. y: unEntier y := unEntier. y ^y Hérite de i-v = { direction } Tortue initialize super initialize. direction := 270 avance: n self av: (Dessin = Slomo ifTrue: [n/2] ifFalse: [n]) av: n n>0 ifTrue: [self y: self y + 1. self av: n – 1.] newInit x=0 y=0 direction = 270 Instance de avance: 10
Héritage Réutilisation Partage Factorisation Classification variables d’instance méthodes des descriptions de 2e type de hiérarchie : graphe d’héritage
Héritage : exemple d’utilisation Point Tortue i-v = { x, y } Méthodes = { x:, y: } i-v = { x, y, direction } Méthodes = { x:, y:, avance } Tortue == Point + epsilon
classVariables = Dessin pool : ICONES { (Smiley, ), (Slomo, ;-) } Tortue class initialize [[true] whileTrue: [ Time avantMidi ifTrue:[ Dessin := Slomo] ifFalse: [ Dessin := Smiley] ]] fork classVariables = Dessin Point class newInit ^self new initialize Hérite de Instance de Instance de i-v = { x, y } Point initialize x := 0. y := 0. y: unEntier y := unEntier. y ^y Hérite de i-v = { direction } Tortue initialize super initialize. direction := 270 avance: n self av: (Dessin = Slomo ifTrue: [n/2] ifFalse: [n]) av: n n>0 ifTrue: [self y: self y + 1. self av: n – 1.] newInit x=0 y=0 direction = 270 Instance de avance: 10
Héritage spécialisation extension de l’environnement La superclasse doit d’abord être définie Variables d’instance méthodes aucune redéfinition ajout (extension) ajout masquage réutilisation directe Possible de modifier l’arbre d’héritage avec sans Héritage est statique calculé une seule fois à la création réutilisation Héritage est dynamique Recherche à chaque réception de messages
Auto-référence Self Super Objet qui a reçu le message Pour qu’un objet puisse invoquer ses propres méthodes Appliquer la méthode la plus spécialisée Méthodes récursives Pour qu’un objet puisse se passer en paramètre Super + modification de l’algorithme de recherche La recherche commence dans la superclasse de la classe où est utilisé “super” Raffiner la factorisation Spécialisation avec réutilisation de méthodes héritées
Les variables Variables temporaires Variables d’instance Allouées le temps d’exécution de la méthode Variables d’instance nommées ou indexées variables privées d’un objet ne sont référençables que par les méthodes de l’objet Variables de classe Partagées par Instances de la classe Instances des sous-classes Variables “pool” Globales Partagées par les instances d’un ensemble de classes Dictionnaire (clé-valeur) Clé = symbole = nom de la variable Les clés sont directement référencées dans les méthodes Variables globales Accessibles de n’importe où dans le système Ex.: noms des classes
classVariables = Dessin pool : ICONES { (Smiley, ), (Slomo, ;-) } Tortue class initialize [[true] whileTrue: [ Time avantMidi ifTrue:[ Dessin := Slomo] ifFalse: [ Dessin := Smiley] ]] fork classVariables = Dessin Point class newInit ^self new initialize Hérite de Instance de Instance de i-v = { x, y } Point initialize x := 0. y := 0. y: unEntier y := unEntier. y ^y Hérite de i-v = { direction } Tortue initialize super initialize. direction := 270 avance: n self av: (Dessin = Slomo ifTrue: [n/2] ifFalse: [n]) av: n n>0 ifTrue: [self y: self y + 1. self av: n – 1.] newInit x=0 y=0 direction = 270 Instance de avance: 10
Model-View-Controller Fondé sur les dépendances Coordonner les activités de plusieurs objets Self changed Self myDependents update Construction d’une interface multi-fenêtres en Smalltalk Modèle (source d’information) texte Contrôleur (interaction de l’usager avec le modèle) clavier Vue (représentation visuelle du modèle) Affichage du texte
doesNotUndertstand: aMessage thisContext become: anObject Réflexivité structurelle opératoire partielle doesNotUndertstand: aMessage thisContext become: anObject perform: aMessage complète métaclasses Héritage multiple Redéfinition du traitement des messages
Conception Typage Encapsulation, interface Pas de vérification à la compilation Les erreurs sont détectées à l’exécution Extension : TypedSmalltalk Encapsulation, interface Modifications locales Pas d’accès externes à l’état d’un objet Seules les méthodes y ont accès Il faut donc définir des méthodes d’accès appropriées Pas de méthodes cachées Polymorphisme et classes abstraites Fondé sur les sélecteurs Classes abstraites Possible de déléguer aux sous-classes l’implémentation d’opérations spécialisées
classVariables = Dessin pool : ICONES { (Smiley, ), (Slomo, ;-) } Tortue class initialize [[true] whileTrue: [ Time avantMidi ifTrue:[ Dessin := Slomo] ifFalse: [ Dessin := Smiley] ]] fork classVariables = Dessin Point class newInit ^self new initialize Hérite de Instance de Instance de i-v = { x, y } Point initialize x := 0. y := 0. y: unEntier y := unEntier. y ^y Hérite de i-v = { direction } Tortue initialize super initialize. direction := 270 avance: n self av: (Dessin = Slomo ifTrue: [n/2] ifFalse: [n]) av: n n>0 ifTrue: [self y: self y + 1. self av: n – 1.] newInit x=0 y=0 direction = 270 Instance de avance: 10