CS 342 Lecture -*- Outline -*- * Inheritance ** Hierarchy of classes draw picture showing Stack, Object, SizedStack see picture on page 281 for collections ** Example: Adding size to stacks recall SizedStack from the smalltalk lecture ---------- (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))) ---------- What code savings? What redundancy (in push: and pop)? can avoid it here by using auxilliary procedures in Stack (define push: (x) (push:Main self x)) (define push:Main (x) (add: elems x)) in SizedStack (define push: (x) ...(push:Main self x)) problem: this requires some foresight can avoid this in real smalltalk using "super" in SizedStack (define push: (x) (begin (set size (+ 1 size)) (push: super x))) *** Inheriting data Recall the layout of storage in instances of SizedStack *the Stack is not contained in the SizedStack (that would be a different design) *** Inheriting operations Recall steps in message sending, emphasize inheritance -infinite loops from calling with self (define push: (x) (begin (set size (+ 1 size)) (push: self x))) ** 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) ------------ discuss how subclasing allows code sharing abstraction ** Single vs. multiple inheritance e.g., what if want SizedCachedStack? *** Single inheritance Inheritance is hierarchical (tree like) in ST. SizedCachedStack has to be subclass of either Sized or Cached *** Multiple inheritance (in CLOS) class can be subclass of many superclasses problems: what if two (or more) define same instance variable or same method? efficiency (have to hash to get instance vars)