Beruflich Dokumente
Kultur Dokumente
root
• An abstract view
self: z instance
– class and instance diagrams
TYPE
BOOK
– terminology: messages, methods, inheritance, IS-A
is-a self:
superclass, subclass, … name: sicp
superclass NAMED-OBJECT copyright: 1996
• Scheme OO system user view instance-of
name:
– conventions on how to write Scheme code to: TYPE
NAME
• define classes CHANGE-NAME
– inherit from other classes is-a
• create instances subclass BOOK
– use instances (invoke methods) private
copyright:
variables
TYPE
ÎScheme OO system implementer view (under the covers) methods YEAR
– How implement instances, classes, inheritance, types
4/6/2004 1 4/6/2004 2
Implementer’s View: get-method and ask Implementer’s View of this in Environ. Model
Warning! Actual version in Project 4 is
• method lookup: (define z (create-book ’sicp 1996)) slightly different, but has the same
general flavor!!
(define (get-method message object) GE z:
(object message))
self: self: self:
handler: name: sicp name: sicp
• "ask" an object to do something - copyright:1996
combined method retrieval and application to args.
named-object- root-part:
(define (ask object message . args) p: message part:
body: (case ...)
(let ((method (get-method message object)))
BOOK
(if (method? method) instance
(apply method args) instance p: message p: message p: message
message handler body: (case ...) body: (case ...) body: (case ...)
(error "No method for message" message))))
1
User’s View: Why a “self” variable? Object-Oriented Design & Implementation
• Every class definition has access to a “self” variable • Focus on classes
– self is a pointer to the entire instance
– Relationships between classes
• Why need this? How or when use self ? – Kinds of interactions that need to be supported between
– When implementing a method, sometimes you “ask” a part of instances of classes
yourself to do something
• E.g. inside a BOOK method, we might…
(ask named-object-part ‘CHANGE-NAME ‘mit-sicp) • Careful attention to behavior desired
– However, sometimes we want to ask the whole instance to do – Inheritance of methods
something
• E.g. inside a subclass, we might – Explicit use of superclass methods
(ask self ‘YEAR) – Shadowing of methods to over-ride default behaviors
• This mostly matters when we have subclass methods that
shadow superclass methods, and we want to invoke one of
those shadowing methods from inside the superclass • An extended example to illustrate class design and
implementation
• Next: An example OO design to illustrate our OO system
4/6/2004 7 4/6/2004 8
4/6/2004 9 4/6/2004 10
4/6/2004 12 4/6/2004 13
2
Professor class implementation Arrogant-Prof class
Is-a
PERSON
PROFESSOR (define ap1 (create-arrogant-prof 'perfect))
(define (create-professor name) name:
(create-instance professor name)) TYPE TYPE (ask ap1 'whoareyou?)
WHOAREYOU? WHOAREYOU? ⇒ (prof perfect)
LECTURE SAY
(define (professor self name)
(let ((person-part (person self name))) (ask ap1 'say '(the sky is blue))
(lambda (message) ⇒ (the sky is blue obviously)
(case message Is-a
((TYPE)
PROFESSOR
(lambda () (type-extend 'professor person-part)))
((WHOAREYOU?) TYPE
(lambda () (list 'prof WHOAREYOU?
(ask person-part 'WHOAREYOU?)))) LECTURE
((LECTURE)
Is-a
(lambda (notes)
(cons 'therefore (ask person-part 'say notes)))) ARROGANT-PROF
(else (get-method message person-part)))))) TYPE
SAY
4/6/2004 14 4/6/2004 15
4/6/2004 16 4/6/2004 17
TYPE
SAY
4/6/2004 18 4/6/2004 19
3
Student class Student implementation
PERSON (define s1 (create-student 'bert)) STUDENT
name: (ask s1 'whoareyou?) TYPE
TYPE ⇒ bert SAY
WHOAREYOU? (define (create-student name)
SAY (create-instance student name))
(ask s1 'say '(i do not understand))
⇒ (excuse me but i do not understand)
(define (student self name)
Is-a (let ((person-part (person self name)))
Is-a
(lambda (message)
PROFESSOR (case message
STUDENT
TYPE ((TYPE)
WHOAREYOU? (lambda () (type-extend 'student person-part)))
LECTURE TYPE ((SAY) (lambda (stuff)
SAY (append '(excuse me but)
Is-a (ask person-part 'say stuff))))
ARROGANT-PROF (else (get-method message person-part))))))
TYPE
SAY
4/6/2004 20 4/6/2004 21
4
Lessons from our example class hierarchy Steps toward our Scheme OOPS:
• Specifying class hierarchies • Basic Objects
– Convention on the structure of a class definition – messages and methods convention
• to inherit structure and methods from superclasses – self variable to refer to oneself
• Control over behavior
• Inheritance
– Can “ask” a sub-part to do something
– internal parts to inherit superclass behaviors
– Can “ask” self to do something
– in local methods, can “ask” internal parts to do
• Use of TYPE information for additional control something
– use get-method on superclass parts to find method if
needed
• Multiple Inheritance Í
4/6/2004 26 4/6/2004 27
4/6/2004 28 4/6/2004 29
(define (singing-arrogant-prof self name) (ask sap1 'say '(the sky is blue))
(let ((singer-part (singer self)) ⇒ (the sky is blue tra la la)
(arr-prof-part (arrogant-prof self name)))
(ask sap1 'lecture '(the sky is blue))
(lambda (message)
⇒ (therefore the sky is blue tra la la)
(case message
((TYPE)
(lambda () (type-extend 'singing-arrogant-prof • See that arrogant-prof’s SAY method is never used in sap1 (no
singer-part “obviously” at end)
arr-prof-part))) – Our get-method passes the SAY message along to the singer class
(else (get-method message singer-part first, so the singer’s SAY method is found
arr-prof-part)))))) • If we needed finer control (e.g. some combination of SAYing)
– Then we could implement a SAY method in singing-arrogant-prof
class to specialize this behavior
4/6/2004 30 4/6/2004 31
5
Implementation View: Multiple Inheritance Summary
• How implement the more general get-method? • Classes: capture common behavior
– Just look through the supplied objects from left to right • Instances: unique identity with own local state
until the first matching method is found.
(define (get-method message object) • Hierarchy of classes
(object message)) – Inheritance of state and behavior from superclass
becomes – Multiple inheritance: rules for finding methods
(define (get-method message . objects)
(define (try objects) • Object-Oriented Programming Systems (OOPS)
(if (null? objects)
– Abstract view: class and instance diagrams
(no-method)
(let ((method ((car objects) message))) – User view: how to define classes, create instances
(if (not (eq? method (no-method))) – Implementation view: how we layer notion of object
method classes, instances, and inheritance on top of standard
(try (cdr objects)))))) Scheme
(try objects))
4/6/2004 32 4/6/2004 33
4/6/2004 34 4/6/2004 35
4/6/2004 36 4/6/2004 37
6
Some Family Relationships – Behaviors Some Family Relationships – Instance Diagram
NAMED-OBJECT
is-a (define a (create-mother 'anne)) a
(define b (create-person 'bob))
PERSON (ask a 'name) ;Value: anne MOTHER
mother: has-a (ask b 'name) ;Value: bob c
name: anne
father: has-a (ask a 'type)
mother: nil
children:
;Value:
has-a list of (mother person named-object root) PERSON
father: nil
father name: cindy children:
(ask b 'type) mother
TYPE mother:
SAY ;Value: (person named-object root) father:
MOTHER children: nil
SET-MOTHER! (define c (ask a 'have-child b 'cindy))
FATHER (define d (ask a 'have-child b 'dan)) b
SET-FATHER! (names-of (ask a 'children)) d
ADD-CHILD ;Value: (dan cindy) PERSON
CHILDREN PERSON name: bob
(names-of (ask b 'children))
is-a name: dan mother: nil
;Value: (dan cindy)
mother: father: nil
MOTHER
(ask d 'name) ;Value: dan father: children:
TYPE (ask (ask d 'mother) 'name) ;Value: anne children: nil
HAVE-CHILD
4/6/2004 38 4/6/2004 39
NAMED-OBJECT
Person Class Definition is-a Mother Class Definition
(define (create-person name) PERSON
(create-instance person name)) mother: PERSON
father:
is-a
(define (person self name)
children: (define (create-mother name)
TYPE (create-instance mother name)) MOTHER
(let ((named-part (named-object self name))
SAY
(mother nil) MOTHER TYPE
(father nil) SET-MOTHER! (define (mother self name) HAVE-CHILD
(children nil))
FATHER (let ((person-part (person self name)))
SET-FATHER!
(lambda (message) ADD-CHILD (lambda (message)
CHILDREN (case message
(case message
((TYPE) (lambda () (type-extend 'person named-part))) ((TYPE) (lambda () (type-extend 'mother person-part)))
((SAY) (lambda (stuff) (display stuff))) ((HAVE-CHILD)
((MOTHER) (lambda () mother)) (lambda (dad child-name)
((FATHER) (lambda () father)) (let ((child (create-person child-name)))
((CHILDREN) (lambda () children)) (ask child 'set-mother! self)
((SET-MOTHER!) (lambda (mom) (set! mother mom))) (ask child 'set-father! dad)
((SET-FATHER!) (lambda (dad) (set! father dad))) (ask self 'add-child child)
((ADD-CHILD) (lambda (child) (ask dad 'add-child child))))
(set! children (cons child children)) (else (get-method message person-part))))))
child))
(else (get-method message named-part))))))
4/6/2004 40 4/6/2004 41
Some Family Relationships – Instance Diagram Some Family Relationships – Instance Diagram
(define a (create-mother 'anne))
a a
(define b (create-person 'bob))
MOTHER MOTHER
child
name: anne name: anne
mother: nil mother: nil
PERSON
father: nil father: nil
children: name: cindy children:
mother:
father:
children: nil
b b
PERSON PERSON
name: bob name: bob
(lambda (dad child-name) mother: nil (lambda (dad child-name) mother: nil
(let ((child (create-person child-name))) father: nil (let ((child (create-person child-name))) father: nil
(ask child 'set-mother! self) children: (ask child 'set-mother! self) children:
(ask child 'set-father! dad) (ask child 'set-father! dad)
(ask self 'add-child child) (ask self 'add-child child)
(ask dad 'add-child child))) (ask dad 'add-child child) ))
4/6/2004 42 4/6/2004 43
7
Result of Result of (define (make-person self name)
(let ((named-part (make-named-object self name))
(create-person ‘cindy) => (create-person ‘cindy) =>(mother nil)
(create-instance make-person ‘cindy) (create-instance make-person
(father‘cindy)
nil)
(children nil))
(lambda (message)
GE GE (case message …))))
c: c:
(define (make-instance)
(let ((handler #f)) self:
(lambda (message) name: cindy
(case message
handler: ((SET-HANDLER!) handler:
(lambda (handler-proc) mother: nil
(set! handler handler-proc))) father: nil
(else (get-method message handler)))) )) children: nil
p: message p: message named-part:
(define (create-instance maker . args)
body: (case ...) body: (case ...)
(let* ((instance (make-instance) )
PERSON (handler (apply maker instance args) )) PERSON (define (create-instance maker . args)
instance (ask instance 'SET-HANDLER! handler) instance (let* ((instance (make-instance) )
instance)) (handler (apply maker
p: message
instance instance body: (case ...) instance args) ))
message handler message handler (ask instance 'SET-HANDLER! handler)
instance))
PERSON
message handler
4/6/2004 44 4/6/2004 (from make-person) 45
Result of (define (make-named-object self name) Result of (define (make-named-object self name)
(let ((root-part (make-root-object self))) (let ((root-part (make-root-object self) ))
(create-person ‘cindy) =>
(lambda (message)
(create-person ‘cindy) =>
(lambda (message)
(create-instance make-person ‘cindy)
(case message …)))) (create-instance make-person ‘cindy)
(case message …))))
GE c:
GE c:
handler: handler:
mother: nil root-part: mother: nil root-part:
father: nil father: nil
children: nil children: nil
p: message named-part: p: message named-part:
body: (case ...) body: (case ...)
Result of
(ask c ‘name)
2. Person handler does not
have ‘NAME method;
Summary
3. Named-object handler
calls get-method on
finds NAME method
1. Calls get-method on handler
named-part • Classes in our system
– May have local state and local methods. Local state can:
• include primitive data (e.g. a name symbol)
• indicate relationships with other objects (e.g. pointers
self: self: self:
name: cindy name: cindy
to other instances in the system)
– May inherit state and methods
handler:
mother: … root-part: • By way of internal handlers generated thru “make-
father: … <superclass>” parts
children: nil
p: message named-part: • Instances in our system
body: (case ...)
– Have a starting “instance” (self) object in env. model
p: message p: message
body: (case ...) body: (case ...) – Instance contains a series of message/state handlers for
p: message
E1: message: name
each class in inheritance chain
body: (case ...)
– You need to gain experience with this!
4. (lambda () name) | E1 Î #[proc 9] E2:
5. (#[proc 9]) | E55 Î name | E2 Î cindy p: name | E2
4/6/2004 48 4/6/2004 49
body: name