(1) Operation Table (2) projector (3) Announcements (4) Make-Pair (5) projector (6) (7) Make-Named- Object (8) projector (9) Ask and Delegate Note: Write Announcement! ON BOARD 3 SLIDE 1 Quizzes available in Recitation tomorrow. Read chapters 1 - 3 of "Learn Java Now" Have a nice vacation! Object-Oriented Programming (in Scheme) 1. Introduction, 5 mins., 10:05 - 10:10 Modeling from Tuesday. ON BOARD 1 Rectangular Polar Real-part Real-part-rect Real-part-polar Imag-part Imag-part-rect Imag-part-polar Magnitude Magnitude-rect Magnitude-polar Angle Angle-rect Angle-polar Prof. Grimson's table with two axes: operations and types gives us three organizational models: 1. The table itself works well for flexibility, but it gets big. And the pieces that are in the table don't tell much of a story by themselves. 2. Make each row into a Scheme procedure: generic procedures that dispatch on the type of the argument. 3. Make each column into a Scheme procedure: object-oriented programming. 2. OO Programming, 5 mins., 10:10 - 10:15 SLIDE 3 1. OO Programming is about conventions for handling local state: ? What is in the state? ? How access is granted to the state? ? How is the state created, initialized, and modified? ? How code for handling the state can be shared for reuse? 2. Terminology: Access to state is via objects. An object can send and receive messages, and has access to various methods for responding to them. 3. Terminology: Objects are created by classes, which specify what state is to be created when a new object is created, what messages the object will process, which methods it will use to process those messages, and what to do if the object receives a message for which it has no method. 4. The classes are related to each other through inheritance or delegation. We'll explore delegation (it's a bit more powerful) but Java uses inheritance. 5. In Scheme, objects and classes are both procedures. The local state is stored in the frames that are created when the procedures are called. This is also true of Java. 3. Simple Example, 5 mins., 10:15 - 10:20 ON BOARD 4 SLIDE 2 (define (make-pair L R) (lambda (msg) (case msg ((LEFT) L) ((RIGHT) R) ((NEW-LEFT!) (lambda (new) (set! L new))) ((NEW-RIGHT!) (lambda (new) (set! R new)))))) (define (left pair) (pair 'LEFT)) (define (set-left! pair new-value) ((pair 'NEW-LEFT!) new-value)) Draw the block structure and argue that the environment model will have the same structure, but one copy per object. Explain that that is where the local state is stored at runtime. 4. Code Base I, 5 mins., 10:20 - 10:25 SLIDE 4 (define (get-method-from-object message object) (object message)) (define get-method get-method-from-object) ; Simplification (define no-method (let ((tag (list 'NO-METHOD))) (lambda () tag))) (define (method? x) (cond ((procedure? x) #T) ((eq? x (no-method)) #F) (else (error "Object returned this non-message:" x)))) SLIDE 5 (define (make-pair L R) (lambda (msg) (case msg ((LEFT) (lambda () L) ((RIGHT) (lambda () R) ((NEW-LEFT!) (lambda (new) (set! L new))) ((NEW-RIGHT!) (lambda (new) (set! R new))) (else (no-method))))))) 5. Delegation, 10 mins., 10:25 - 10:35 Idea: capture common information (state and methods) for reuse rather than reinvention. Idea: when you want to have some behavior, create an object that has that behavior as part of your local state, and then delegate work to it when needed. Problem: you have to know who you are, so that operations that work differently with you will have your special stamp on them. "If I delegate a task to you, I expect you to do it the way I would have done it." Solution: Every method has a first argument that is the "self" on whose behalf the operation is performed. Draw the hierarchy we'll use today: Named Object ? Place ? Physical Object ? Mobile Object ? Things So let's look at the simplest kind of object, a Named-Object: SLIDE 6 (define (make-named-object name) ;; All objects inherit from this, so we are guaranteed that any ;; object can respond to the messages NAME, INSTALL, and SAY. (install-shield ; Ignore for now (lambda (message) (case message ((NAMED-OBJECT?) (lambda (self) #T)) ((NAME) (lambda (self) name)) ((SAY) (lambda (self list-of-stuff) (if (not (null? list-of-stuff)) (display-message list-of-stuff)) 'NUF-SAID)) ((INSTALL) (lambda (self) 'INSTALLED)) (else (no-method)))))) How do we ask a NAMED-OBJECT to do something? BOARD 9 (define (delegate to from message . args) (let ((method (get-method message to))) (if (method? method) (apply method from args)) (error "No method for" message)))) (define (ask object message . args) (apply delegate object object message args)) ON LINE (define Jim (make-named-object "Jim")) (ask jim `name) How does a PLACE delegate to its NAMED-OBJECT? SLIDE 7 (define (make-place name) (let ((neighbor-map '()) ; Alist, direction -> object (things '()) (named-obj (make-named-object name))) (install-shield (lambda (message) (case message ((PLACE?) (lambda (self) #T)) ... (else (get-method message named-obj))))))) ON LINE (define Lecture-hall (make-named-object "10-250")) (ask lecture-hall `name) 6. Code Review, 15 mins., 10:35 - 10:50 7. Review, 5 mins., 10:50 - 10:55 Object-oriented programming is a way of codifying columns of our underlying "operations table" model. Objects are the gateway for access to local state. Classes are models for creating objects, expressing both the state that must be created, the messages that objects handles, the methods used to respond to those messages, and what to do if a message isn't handled. Delegation involves asking another object to supply a method for handling a message, then using that method but specifying yourself as the object doing the work. There's a lot of code. 1 4