OOPS One more example Goal See an example

  • Slides: 28
Download presentation
OOPS – One more example • Goal: See an example that distinguishes between –

OOPS – One more example • Goal: See an example that distinguishes between – “is-a” or inheritance relationships – “has-a” or local variable relationships • Idea: – A person class with parent-child relationships 4/6/2004 1

Different Views of Object-Oriented System • An abstract view – class and instance diagrams

Different Views of Object-Oriented System • An abstract view – class and instance diagrams – terminology: messages, methods, inheritance, superclass, subclass, … • Scheme OO system user view – conventions on how to write Scheme code to: • define classes – inherit from other classes • create instances – use instances (invoke methods) èScheme OO system implementer view (under the covers) – How implement instances, classes, inheritance, types 4/6/2004 2

Reminder: Example Class/Instance Diagram root TYPE IS-A BOOK self: name: sicp copyright: 1996 is-a

Reminder: Example Class/Instance Diagram root TYPE IS-A BOOK self: name: sicp copyright: 1996 is-a superclass instance z self: NAMED-OBJECT instance-of name: TYPE NAME CHANGE-NAME is-a subclass private variables methods 4/6/2004 BOOK copyright: TYPE YEAR 3

Implementer’s View of this in Environ. Model (define z (create-book ’sicp 1996)) GE z:

Implementer’s View of this in Environ. Model (define z (create-book ’sicp 1996)) GE z: handler: p: message body: (case. . . ) self: name: sicp copyright: 1996 self: name: sicp named-objectpart: root-part: self: BOOK instance message handler p: message body: (case. . . ) BOOK message handler 4/6/2004 NAMED-OBJECT message handler root message handler 4

Implementer’s View: Instances (define (make-instance) (let ((handler #f)) (lambda (message) (case message ((SET-HANDLER!) (lambda

Implementer’s View: Instances (define (make-instance) (let ((handler #f)) (lambda (message) (case message ((SET-HANDLER!) (lambda (handler-proc) (set! handler-proc))) (else (get-method message handler)))))) (define (create-instance maker. args) (let* ((instance (make-instance)) (handler (apply maker instance args))) (ask instance 'SET-HANDLER! handler) instance)) 4/6/2004 5

Implementer’s View: get-method and ask • method lookup: (define (get-method message object) (object message))

Implementer’s View: get-method and ask • method lookup: (define (get-method message object) (object message)) • "ask" an object to do something combined method retrieval and application to args. (define (ask object message. args) (let ((method (get-method message object))) (if (method? method) (apply method args) (error "No method for message" message)))) (apply op args) (op arg 1 arg 2 … argn) 4/6/2004 6

Implementer’s View of this in Environ. Model (define z (create-book ’sicp 1996)) GE z:

Implementer’s View of this in Environ. Model (define z (create-book ’sicp 1996)) GE z: handler: p: message body: (case. . . ) self: name: sicp copyright: 1996 self: name: sicp named-objectpart: root-part: self: BOOK instance message handler p: message body: (case. . . ) BOOK message handler 4/6/2004 NAMED-OBJECT message handler root message handler 7

Steps toward our Scheme OOPS: • Basic Objects – messages and methods convention –

Steps toward our Scheme OOPS: • Basic Objects – messages and methods convention – self variable to refer to oneself • Inheritance – internal parts to inherit superclass behaviors – in local methods, can “ask” internal parts to do something – use get-method on superclass parts to find method if needed • Multiple Inheritance 4/6/2004 8

A Singer, and a Singing-Arrogant-Prof PERSON name: TYPE WHOAREYOU? SAY QUESTION ANSWER Is-a PROFESSOR

A Singer, and a Singing-Arrogant-Prof PERSON name: TYPE WHOAREYOU? SAY QUESTION ANSWER Is-a PROFESSOR A singer is not a person. A singer has a different SAY that always ends in "tra la la". A singer starts to SING with "the hills are alive" SINGER TYPE WHOAREYOU? LECTURE Is-a TYPE SAY SING is-a ARROGANT-PROF TYPE SAY ANSWER 4/6/2004 S-A-P 9

Singer implementation (define (create-singer) (create-instance make-singer)) SINGER TYPE (define (make-singer self) SAY (let ((root-part

Singer implementation (define (create-singer) (create-instance make-singer)) SINGER TYPE (define (make-singer self) SAY (let ((root-part (make-root-object self))) SING (lambda (message) (case message ((TYPE) (lambda () (type-extend 'singer root-part))) ((SAY) (lambda (stuff) (append stuff '(tra la la)))) ((SING) (lambda () (ask self 'say '(the hills are alive)))) (else (get-method message root-part)))))) • The singer is a "base" class (its only superclass is root) 4/6/2004 10

Singing-Arrogant-Prof implementation ARROGANTPROF (define (create-singing-arrogant-prof name) (create-instance make-singing-arrogant-prof name)) SINGER S-A-P (define (make-singing-arrogant-prof self

Singing-Arrogant-Prof implementation ARROGANTPROF (define (create-singing-arrogant-prof name) (create-instance make-singing-arrogant-prof name)) SINGER S-A-P (define (make-singing-arrogant-prof self name) (let ((singer-part (make-singer self)) (arr-prof-part (make-arrogant-prof self name))) (lambda (message) (case message ((TYPE) (lambda () (type-extend 'singing-arrogant-prof singer-part arr-prof-part))) (else (get-method message singer-part arr-prof-part)))))) 4/6/2004 11

Example: A Singing Arrogant Professor (define sap 1 (create-singing-arrogant-prof 'zoe)) (ask sap 1 'whoareyou?

Example: A Singing Arrogant Professor (define sap 1 (create-singing-arrogant-prof 'zoe)) (ask sap 1 'whoareyou? ) Þ (prof zoe) (ask sap 1 'sing) Þ (the hills are alive tra la la) (ask sap 1 'say '(the sky is blue)) Þ (the sky is blue tra la la) (ask sap 1 'lecture '(the sky is blue)) Þ (therefore the sky is blue tra la la) • See that arrogant-prof’s SAY method is never used in sap 1 (no “obviously” at end) – Our get-method passes the SAY message along to the singer class first, so the singer’s SAY method is found • 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 12

Implementation View: Multiple Inheritance • How implement the more general get-method? – Just look

Implementation View: Multiple Inheritance • How implement the more general get-method? – Just look through the supplied objects from left to right until the first matching method is found. (define (get-method message object) (object message)) becomes (define (get-method message. objects) (define (try objects) (if (null? objects) (no-method) (let ((method ((car objects) message))) (if (not (eq? method (no-method))) method (try (cdr objects)))))) (try objects)) 4/6/2004 13

Some Classes for Family Relationships ROOT-OBJECT is-a NAMED-OBJECT is-a PERSON is-a MOTHER 4/6/2004 •

Some Classes for Family Relationships ROOT-OBJECT is-a NAMED-OBJECT is-a PERSON is-a MOTHER 4/6/2004 • Look at these classes (named-object, person, mother) from perspectives of – class diagrams – desired behaviors – instance diagrams – our class/method definitions – underlying representation (environment model) 14

Named-object class definition (define (create-named-object name) (create-instance make-named-object name)) ROOT-OBJECT is-a NAMED-OBJECT name: (define

Named-object class definition (define (create-named-object name) (create-instance make-named-object name)) ROOT-OBJECT is-a NAMED-OBJECT name: (define (make-named-object self name) (let ((root-part (make-root-object self))) TYPE (lambda (message) NAME (case message ((TYPE) (lambda () (type-extend 'named-object root-part))) ((NAME) (lambda () name)) (else (get-method message root-part)))))) (define (names-of objects) ; Given a list of objects, returns a list of their names. (map (lambda (x) (ask x 'NAME)) objects)) • Very simple state and behavior: a local name, which the user can access through NAME method. 4/6/2004 15

Some Family Relationships – Class Diagram NAMED-OBJECT is-a PERSON mother: father: children: TYPE SAY

Some Family Relationships – Class Diagram NAMED-OBJECT is-a PERSON mother: father: children: TYPE SAY MOTHER SET-MOTHER! FATHER SET-FATHER! ADD-CHILDREN is-a • person inherits from named-object • local state: a person now… has-a – has-a mother (of type mother) has-a – has-a father (of type person) has-a list of – has-a list of children (of type person) • additional person methods to manage state • a mother inherits from person – adds the have-child method MOTHER TYPE HAVE-CHILD 4/6/2004 16

Some Family Relationships – Behaviors NAMED-OBJECT is-a PERSON mother: father: children: TYPE SAY MOTHER

Some Family Relationships – Behaviors NAMED-OBJECT is-a PERSON mother: father: children: TYPE SAY MOTHER SET-MOTHER! FATHER SET-FATHER! ADD-CHILDREN is-a MOTHER TYPE HAVE-CHILD 4/6/2004 (define a (create-mother 'anne)) (define b (create-person 'bob)) (ask a 'name) ; Value: anne has-a (ask b 'name) ; Value: bob has-a (ask a 'type) ; Value: (mother person named-object root) has-a list of father mother (ask b 'type) ; Value: (person named-object root) (define c (ask a 'have-child b 'cindy)) (define d (ask a 'have-child b 'dan)) (names-of (ask a 'children)) ; Value: (dan cindy) (names-of (ask b 'children)) ; Value: (dan cindy) (ask d 'name) (ask d 'mother) 'name) ; Value: dan ; Value: anne 17

Some Family Relationships – Instance Diagram a MOTHER name: anne mother: nil father: nil

Some Family Relationships – Instance Diagram a MOTHER name: anne mother: nil father: nil children: c PERSON name: cindy mother: father: children: nil b d PERSON name: dan mother: father: children: nil 4/6/2004 PERSON name: bob mother: nil father: nil children: 18

Person Class Definition (define (create-person name) (create-instance make-person name)) NAMED-OBJECT is-a PERSON mother: father:

Person Class Definition (define (create-person name) (create-instance make-person name)) NAMED-OBJECT is-a PERSON mother: father: children: (define (make-person self name) TYPE (let ((named-part (make-named-object self name)) SAY (mother nil) MOTHER SET-MOTHER! (father nil) FATHER (children nil)) SET-FATHER! ADD-CHILD (lambda (message) CHILDREN (case message ((TYPE) (lambda () (type-extend 'person named-part))) ((SAY) (lambda (stuff) (display stuff))) ((MOTHER) (lambda () mother)) ((FATHER) (lambda () father)) ((CHILDREN) (lambda () children)) ((SET-MOTHER!) (lambda (mom) (set! mother mom))) ((SET-FATHER!) (lambda (dad) (set! father dad))) ((ADD-CHILD) (lambda (child) (set! children (cons children)) child)) (else (get-method message named-part)))))) 4/6/2004 19

Mother Class Definition PERSON (define (create-mother name) (create-instance make-mother name)) is-a MOTHER TYPE (define

Mother Class Definition PERSON (define (create-mother name) (create-instance make-mother name)) is-a MOTHER TYPE (define (make-mother self name) HAVE-CHILD (let ((person-part (make-person self name))) (lambda (message) (case message ((TYPE) (lambda () (type-extend 'mother person-part))) ((HAVE-CHILD) (lambda (dad child-name) (let ((child (create-person child-name))) (ask child 'set-mother! self) (ask child 'set-father! dad) (ask self 'add-child) (ask dad 'add-child)))) (else (get-method message person-part)))))) 4/6/2004 20

Some Family Relationships – Instance Diagram (define a (create-mother 'anne)) (define b (create-person 'bob))

Some Family Relationships – Instance Diagram (define a (create-mother 'anne)) (define b (create-person 'bob)) a MOTHER name: anne mother: nil father: nil children: b (lambda (dad child-name) (let ((child (create-person child-name))) (ask child 'set-mother! self) (ask child 'set-father! dad) (ask self 'add-child) (ask dad 'add-child))) 4/6/2004 PERSON name: bob mother: nil father: nil children: 21

Some Family Relationships – Instance Diagram a MOTHER name: anne mother: nil father: nil

Some Family Relationships – Instance Diagram a MOTHER name: anne mother: nil father: nil children: child PERSON name: cindy mother: father: children: nil b (lambda (dad child-name) (let ((child (create-person child-name))) (ask child 'set-mother! self) (ask child 'set-father! dad) (ask self 'add-child) (ask dad 'add-child) )) 4/6/2004 PERSON name: bob mother: nil father: nil children: 22

Result of (create-person ‘cindy) => (create-instance make-person ‘cindy) GE c: handler: p: message body:

Result of (create-person ‘cindy) => (create-instance make-person ‘cindy) GE c: handler: p: message body: (case. . . ) PERSON instance (define (make-instance) (let ((handler #f)) (lambda (message) (case message ((SET-HANDLER!) (lambda (handler-proc) (set! handler-proc))) (else (get-method message handler)))) )) (define (create-instance maker. args) (let* ((instance (make-instance) ) (handler (apply maker instance args) )) (ask instance 'SET-HANDLER! handler) instance)) instance message handler 4/6/2004 23

(define (make-person self name) Result of (let ((named-part (make-named-object (create-person ‘cindy) =>(mother nil) (create-instance

(define (make-person self name) Result of (let ((named-part (make-named-object (create-person ‘cindy) =>(mother nil) (create-instance make-person (father‘cindy) nil) GE self name)) (children nil)) (lambda (message) (case message …)))) c: self: name: cindy handler: p: message body: (case. . . ) mother: nil father: nil children: nil named-part: PERSON instance p: message instance body: (case. . . ) message handler PERSON message handler 4/6/2004 (from make-person) (define (create-instance maker. args) (let* ((instance (make-instance) ) (handler (apply maker instance args) )) (ask instance 'SET-HANDLER! handler) instance)) 24

(define (make-named-object self name) Result of (let ((root-part (make-root-object self))) (create-person ‘cindy) => (lambda

(define (make-named-object self name) Result of (let ((root-part (make-root-object self))) (create-person ‘cindy) => (lambda (message) (create-instance make-person ‘cindy) (case message …)))) GE c: self: name: cindy mother: nil father: nil children: nil named-part: root-part: handler: p: message body: (case. . . ) PERSON instance p: message body: (case. . . ) p: message instance body: (case. . . ) message handler PERSON message handler 4/6/2004 (from make-person) NAMED-OBJECT message handler 25

(define (make-named-object self name) Result of (let ((root-part (make-root-object self) (create-person ‘cindy) => (lambda

(define (make-named-object self name) Result of (let ((root-part (make-root-object self) (create-person ‘cindy) => (lambda (message) (create-instance make-person ‘cindy) (case message …)))) GE )) c: self: name: cindy mother: nil father: nil children: nil named-part: root-part: self: handler: p: message body: (case. . . ) PERSON instance p: message body: (case. . . ) p: message instance body: (case. . . ) message handler PERSON message handler 4/6/2004 (from make-person) NAMED-OBJECT message handler root message handler 26

Result of (ask c ‘name) 1. Calls get-method on handler 2. Person handler does

Result of (ask c ‘name) 1. Calls get-method on handler 2. Person handler does not have ‘NAME method; calls get-method on named-part 3. Named-object handler finds NAME method self: name: cindy mother: … father: … children: nil named-part: root-part: self: handler: p: message body: (case. . . ) E 1: message: name 4. (lambda () name) | E 1 #[proc 9] 5. (#[proc 9]) | E 55 name | E 2 cindy p: 4/6/2004 body: name E 2: name | E 2 27

Summary • Classes in our system – May have local state and local methods.

Summary • 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 to other instances in the system) – May inherit state and methods • By way of internal handlers generated thru “make<superclass>” parts • Instances in our system – Have a starting “instance” (self) object in env. model – Instance contains a series of message/state handlers for each class in inheritance chain – You need to gain experience with this! 4/6/2004 28