Académique Documents
Professionnel Documents
Culture Documents
par Objets sur les actions et/ou les calculs qui vont traiter les données :
- soit par manipulation explicite de la mémoire via
l'exécution d'instructions : programmation impérative.
("soft" et "hard") - soit de manière implicite en privilégiant l'évaluation
d'expressions : programmation fonctionnelle.
Peut-on ré-initialiser une mémoire privée ? Les objets "softs" [Scheme pur]
• Revenons au générateur d'entiers pairs :
OK
> (define fermat (make-gpair))
> (for ([i (in-range 1 11)]) Ô Fermat, ré-initialise
(printf "~a " (fermat))) ton compteur à 3 !
0 2 4 6 8 10 12 14 16 18
Un exemple de classe avec la vraie couche-objet Racket • L'envoi de message passe par la macro send :
• On peut envoyer à un objet de la classe point2d un message public : En Python 3 : Comparez avec le code
> (send a pos) Scheme de la page 9…
class Point2d : # Python 3
(10 20)
nbPoints = 0
> (send a move 2 5)
def __init__(self,x=0,y=0) :
> (send a toString)
self.x = x
"point2d[12,25]"
self.y = y
Point2d.nbPoints++
• On peut aussi lui envoyer une cascade de messages publics : def getX(self) : # inutile ? x est public
return self.x
> (send* a (move -1 0) (pos)) def getY(self) :
(11 25) return self.y
def move(self,dx,dy) :
• Il est bien entendu impossible d'utiliser de l'extérieur de la classe self.x = self.x + dx
self.y = self.y + dy
une méthode privée [non déclarée publique] :
def __concat_infos(self) : # private ?
> (send a concat-infos) return 'point2d[{},{}]'.format(self.x,self.y)
ERROR : no method concat-infos for class point2d% def __repr__(self) :
return self.__concat_infos()
Exécution au toplevel de Python : La hiérarchie des classes - L'héritage
>>> p = Point2d(3,5)
(define point2d%
>>> q = Point2d(100)
>>> (p.getX(),p.getY()) (class object%
(3, 5) ...))
>>> (q.getX(),q.getY())
(100, 0) • Toute classe est une sous-classe de object%, qui est donc à la racine
>>> q
de l'arbre des classes :
point2d[100,0] private ?
>>> nbPoints (define coloredPoint2d%
NameError: name 'nbPoints' is not defined object% (class point2d%
>>> Point2d.nbPoints ...))
2
>>> q.__concat_infos()
AttributeError: 'Point2d' object has no attribute '__concat_infos' .... point2d% .... La classe coloredPoint2d% :
- étend la classe point2d%
• En réalité, le coup du __ en préfixe de concat_infos est un leurre : - est une sous-classe de point2d%
>>> dir(q) # oups ! coloredPoint2d% - admet point2d% comme classe-mère
['_Point2d__concat_infos', ...]
>>> p._Point2d__concat_infos() Java class ColoredPoint2d extends Point2d
point2d[3,5] Python
13 class ColoredPoint2d(Point2d)
• Une sous-classe peut ajouter de nouveaux champs et de nouvelles • Mais une sous-classe peut aussi modifier le comportement, en
méthodes, donc créer des point2d particuliers : redéfinissant [overriding] certaines méthodes de sa classe-mère :
• Si l'on veut exprimer que la classe point2d% implémente l'interface EXEMPLE : la classe des listes circulaires
forme<%> :
• Une liste circulaire sera une (define circ-list%
Scheme (define point2d%
liste dotée d'une méthode next
(class object%
(class* object% (forme<%>) (init-field (contenu empty))
...)) qui retourne l'élément courant, (define ptr contenu)
en avançant vers l'élément (define/public (next)
Java class Point2d extends Object implements Forme { suivant. Mais à la fin de la liste, (let ((x (car ptr)))
... (if (null? (cdr ptr))
} on revient automatiquement au
(set! ptr contenu)
début ! (set! ptr (cdr ptr)))
• Une classe peut implémenter plusieurs interfaces !
x))
(define A% (super-new)))
(class* B% (I<%> ...)
...)) > (define LC (make-object circ-list% '(a b c)))
• Contrairement aux classes, on ne peut pas instancier une interface :
> (send LC next) > (send LC next)
a c
> (new forme<%>)
> (send LC next) > (send LC next)
Expected argument of type class; given interface forme<%>
b a
etc.
Les primitives (non-objet) de la Tortue (TP5)
graphisme graphisme
polaire cartésien
λ
adt-turtle.rkt
21