150 likes | 353 Views
Inheritance. Share and reuse classes with modifications to fields and methods Improve programmer productivity and aid code evolution. Delegation. ( define make-bounded-stack ( lambda (n) ( let ((bound n) (stk (make-stack))) ( lambda (message) ( case message
E N D
Inheritance Share and reuse classes with modifications to fields and methods Improve programmer productivity and aid code evolution L15Inh
Delegation (define make-bounded-stack (lambda (n) (let ((bound n) (stk (make-stack))) (lambda (message) (case message ((push!) (if (< ((stk 'local-pushed)) bound) (stk 'push!) (error ”Overflow”))) ((set-bound!) (lambda (x) (set! bound x))) ((set-stack!) (lambda (s) (set! stk s))) (else(stk message)) ) )))) L15Inh
Inheritance define boundedstackclass = class stackclass, () (bound) (initialize = method () begin &bound := 10; $initialize(super) end; push = method (x) if less(&localpushed, &bound) then $push(super, x) else error(); setbound = method (x) &bound := x ) &&pushed := 0 • Specify only incremental changes. • Access parent’s version of a method through super. L15Inh
Code sharing by organization of objects. Delegate message handling. Dynamic and flexible. When and how to delegate can depend on system state. E.g., Java 1.1 Event Model Code sharing by organization of classes. Single vs multiple inheritance. Static but efficient. Type determines message interpretation. E.g., Java 1.0 Event Model Delegation vs Inheritance L15Inh
Inheritance in Java class Boundedstackclass extends Stack { private int bound; Boundedstackclass() { super(); bound = 10; } publicvoid push(Object x) { if (size() < bound) super.push(x); elsenew Exception(”Overflow”); } publicvoid setbound(int x){ bound = x; } } • Specify only incremental changes. • Access parent’s version of a method through super. L15Inh
Composition and Delegation in Java class Boundedstackclass { private int bound; privateStack stk; Boundedstackclass() { stk = new Stack(); bound = 10; } publicvoid push(Object x) { if (size() < bound) stk.push(x); elsenew Exception(”Overflow”); } publicvoid setbound(int x){ bound = x; } public Object top() { returnstk.top(); } ... Explicit list of other delegated stack methods } L15Inh
Additional Syntax <exp> ::= class <exp>, <c-vars> <i-vars> <methdecls> <exp> new-class (parent-exp c-vars i-vars methdecls init-exp) | $<var> <super-rands> super-meth-app (name rands) <super-rands> ::= (super) | (super, <exps>) L15Inh
Representing classes • Class record is modified as follows: ( define-record class (parent c-vars c-vals i-vars m-env) ) • List of newly introduced class variables and instance variables are appended to those of its parents to obtain subclass variables. • Field name conflicts resolved through hiding. • Instance record remains unaltered. • super implies searching in parent’s method environment (to reuse the overridden definition). L15Inh
Introducing Inheritance into Interpreter (define eval-exp (lambda (exp env class inst) (variant-case exp ... subclass definition parent-method-invocation (else ...) ) )) L15Inh
(new-class (parent-exp c-vars i-vars methdecls init-exp) (let ( ( pclass (eval-exp parent-exp env class inst) ) ( oms (map (lambda (d) (eval-exp (decl->exp d) env class inst)) methdecls) ) ) (let( (nc-vars (append c-vars (class->c-vars pclass))) (ni-vars (append i-vars (class->i-vars pclass))) ) (letrec ((tclass (make-class pclass nc-vars (make-vals nc-vars) ni-vars (extend-env (map decl->var methdecls) (map (lambda (om) (om (lambda () tclass))) oms) (class->m-env pclass) )))) (eval-exp init-exp env tclass (make-instance tclass '#())) tclass)) ) ) L15Inh
(super-meth-app (name rands) (let ((args (map (lambda (x) (eval-exp x env class inst)) rands) )) ( meth-call name (class->parent class) (cons inst args)) ) ) • Note that due to this clause, a method defined in a (parent) class can be invoked on an instance of its (descendent) subclass. (Coercion) • Recall also that the list of instance/class variables has variables from more specific (sub)-class before less specific (super)-class. (Efficient Append.) • Recall also that the vector of values has values for variables due to more specific (sub)-class at a higher index than those due to less specific (super)-classes.(Reversal) L15Inh
(define init-env (extend-env '(parentof classof baseobject) (map make-cell (list (make-prim-proc 'class->parent) (make-prim-proc 'instance->class) (make-class '* '() '#() '() init-meth-env) ) ) base-env) ) • Recall that base-env interprets primitive procedures and symbols, and init-meth-env contains default constructor. L15Inh
Scoping: Lexical vs Static class A { static int cv; int iv; } class Test { public static void main(String [] args){ int iv, cv; class B extends A { void print() { System.out.print( “”+ cv + iv ); /*error*/ System.out.println( “”+this.cv +this.iv ); } } new B(). print(); } } L15Inh
Scoping: Dynamic vs Static class A { static int cv = 10; int iv = 70; int f() {return 40;} void print() { System.out.println( “”+ cv + iv + f()); }} class B extends A { static int cv = 33 ; int iv = 88; int f() {return 55;} } class Test2 { public static void main(String [] args){ new A(). print(); new B(). print(); }} L15Inh
Advanced Topics • Multiple Inheritance • E.g., C++, Eiffel. • Meta-classes • E.g., Smalltalk. • Inner/Nested classes • E.g., Java. • Static Typing • E.g., ML, Haskell. L15Inh