II. Object-oriented design: coping with change A. Motivation 1. The problem: coping with change in software 2. partial solution: information hiding and data abstraction as in CLU 3. other problems: reuse of designs regularity, user extensions to system B. Objects = data + operations C. Classes ---------------- (class Stack Object (elems) ; instance variables (like the rep) (define initStack () (begin (set elems (mkList)) self)) ; have to return created object (define push: (x) (add: elems x)) (define pop () (removeFirst elems)) (define top () (car elems)) (define isEmpty () (isEmpty elems)) (define print () ; useful for debugging (begin (print #Stack) (printAux self (first elems)))) (define printAux (e) (begin (while (notNil e) (begin (print e) (set e (next elems)))) self)) ) (define mkStack () (initStack (new Stack))) (set myStack (mkStack)) ---------------- 1. Inheritance 2. Example: Adding size to stacks ---------- (class SizedStack Stack (size) (define initSizedStack () (begin (initStack self) (set size 0) self)) (define size () size) (define push: (x) (begin (set size (+ 1 size)) (add: elems x))) (define pop () (begin (set size (- 1 size)) (removeFirst elems))) ) (define mkSizedStack () (initSizedStack (new SizedStack))) (set sStack (mkSizedStack)) ---------- 3. Inheriting data D. Message Passing (generic invocation, dynamic binding) 1. message = operation name + arguments ------------------ (push: myStack 4) (print (top myStack)) (pop myStack) (push: sStack 2) ------------------ 2. implementation (in Smalltalk) ---------------- Steps in message sending: let receiver = object that is sent message let c = class of receiver 1. [fetch] look for method in class c found: go to step 2 not found: if c is Object give error, else goto 1. 2. [call] bind formals to actuals and execute the code of the method ---------------- 3. Message Passing and binding times a. early (static) binding b. delayed (late, dynamic) binding --------------- (define assignMyStack (b) (if b (set myStack (mkStack)) (set myStack (mkSizedStack)))) (push: myStack 4) --------------- E. When to use message passing (dynamic binding) in design? III. Smalltalk A. Syntax 1. function definitions and expressions same as chapter 1 2. symbols 3. Classes ------------------------------- Smalltalk CLU (xCord yCord) (rep xCord yCord) (set xCord x) (set-xCord p x) xCord (xCord p) self p (define rotate () (define rotate (p) ... self...) ...p ...) ------------------------------- B. in class exercise: write something like the Point cluster IV. Inheritance A. Hierarchy of classes B. Example: Adding size to stacks 1. Inheriting data 2. Inheriting operations C. Example: CachedStack ---------- (class CachedStack Stack (cache) (define initCachedStack () (begin (initStack self) (set cache #nil) self)) (define push: (anElem) (if (notNil cache) (begin (add: elems cache) (set cache anElem)) (set cache anElem))) (define pop () (if (isNil cache) (removeFirst elems) (set cache #nil))) (define top () (if (notNil cache) cache (car elems))) (define isEmpty () (and (isNil cache) (isEmpty elems))) (define print () (begin (print #Stack) (if (notNil cache) (print cache) 0) (printAux self (first elems)))) ) (define mkCachedStack () (initCachedStack (new CachedStack))) ---------- ------------ ; example of use (set c (mkCachedStack)) (push: c 1) (push: c 2) ------------ D. Single vs. multiple inheritance 1. Single inheritance 2. Multiple inheritance (in CLOS) V. Type Checking in Smalltalk A. Strong B. Dynamic VI. Implementation of Smalltalk A. Storage Manager 1. objects 2. class objects 3. message dictionaries 4. activation records (contexts) VII. Analysis of Smalltalk A. Major difference between Little Smalltalk and Smalltalk-80 1. class methods 2. instance variable name scope 3. indexed instance variables