340 likes | 359 Views
Dive into the concepts of inheritance, polymorphism, and design by contract with Bertrand Meyer's OOSC lectures. Explore inheritance vs. genericity, dynamic binding, and redefinition of features.
E N D
Object-Oriented Software Construction Bertrand Meyer OOSC Summer Semester 2004
Lecture 7: Inheritanceby Piotr Nienaltowski OOSC Summer Semester 2004
What do you want to learn today? • What is inheritance? • Redefinition of features • Polymorphism and dynamic binding • Inheritance and Design by Contract • Inheritance vs. genericity • Assignment attempt OOSC Summer Semester 2004
What is inheritance? • Principle: Describe a new class not from scratch but as extension or specialization of one existing class — or several in the case of MULTIPLE inheritance. • From the module viewpoint: if B inherits from A, all the services of A are potentially available in B (possibly with a different implementation). • From the type viewpoint: inheritance is the ‘‘is-plus-but-except’’ relation. If B inherits from A, whenever an instance of A is required, an instance of B will be acceptable. OOSC Summer Semester 2004
Terminology • Parent, Heir • Ancestor, Descendant • The ancestors of B are B itself and the ancestors of its parents. • Proper ancestor, Proper descendant • Direct instance, Instance • The instances of A are the direct instances of its descendants. • (Other terminology: subclass, superclass, base class) feature A feature B OOSC Summer Semester 2004
Example hierarchy extent* display* * deferred + effective ++ redefined barycenter* * rotate … FIGURE … * * OPEN_ FIGURE CLOSED_ FIGURE perimeter* perimeter+ perimeter+ + + SEGMENT POLYLINE POLYGON ELLIPSE diagonal perimeter++ ... ... side1 TRIANGLE RECTANGLE side2 CIRCLE perimeter++ perimeter++ SQUARE OOSC Summer Semester 2004
Redefinition classPOLYGON create make feature vertices: ARRAY [POINT] vertices_count: INTEGER perimeter: REALis -- Perimeter length do from...until...loop Result :=Result + (vertices @ i).distance (vertices @ (i + 1)) ... endend invariant vertices_count >= 3 vertices_count = vertices.countend vertices @ i vertices @ (i + 1) OOSC Summer Semester 2004
Redefinition (cont’d) classRECTANGLEinherit POLYGON redefine perimeter endcreate make featurediagonal, side1, side2: REAL perimeter: REALis -- Perimeter length do Result := 2 *(side1 + side2) end invariantvertices_count = 4end side2 side1 OOSC Summer Semester 2004
Inheritance, typing and polymorphism • Assume: p: POLYGON; r: RECTANGLE; t: TRIANGLE; x: REAL • Permitted: x := p.perimeter x := r.perimeter x := r.diagonal p := r • NOT permitted: x := p.diagonal (even just after p := r !) r := p p (POLYGON) r (RECTANGLE) OOSC Summer Semester 2004
Dynamic binding • What is the effect of the following (assuming some_test true)? ifsome_testthen p := r else p := t end x := p.perimeter • Redefinition: A class may change an inherited feature, as with RECTANGLE redefining perimeter. • Polymorphism: p may have different forms at run-time. • Dynamic binding: Effect of p.perimeter depends on run-time form of p. OOSC Summer Semester 2004
The meaning of inheritance • The type perspective: • Automatic adaptation of operations to the dynamic form of their targets (extendibility):Representation independence. • Factoring out reusable operations: Commonality. • The module perspective (reusability): • Open-closed modules • Modularity • The Single Choice Principle OOSC Summer Semester 2004
The traditional architecture display (f: FIGURE) is do if‘‘f is a CIRCLE’’then ... elseif‘‘f is a POLYGON’’then ... end end and similarly for all other routines! OOSC Summer Semester 2004
Applying the Single Choice Principle f: FIGURE c: CIRCLE p: POLYGON ... createc.make (...) createp.make (...) ... if ... then f := c else f := p end ... f.move (...) f.rotate (...) f.display (...) ... OOSC Summer Semester 2004
The Open-Closed Principle B A C E D F A’ H I G OOSC Summer Semester 2004
The dangers of static binding createa.make (…) • For every creation procedure cp: {precp} docp {postcp and INV} • For every exported routine r: {INV and prer} dor {INV and postr} • The worst possible erroneous run-time situation in object-oriented software development: • Producing an object that does not satisfy the invariant of its class. S1 a.f (…) S2 a.g (…) S3 a.f (…) S4 OOSC Summer Semester 2004
The dangers of static binding (cont’d) • {INVA} dorA {INVA} • {INVB} dorB {INVB} • Consider a call of the form a1.r where a1 is polymorphic: • No guarantee on the effect of dorA on an instance of B! rA A rB++ B OOSC Summer Semester 2004
A concrete example w: WINDOW b: BUTTON createb w:= b w.display display WINDOW display++ BUTTON OOSC Summer Semester 2004
Using original version of redefined feature classBUTTONinherit WINDOWredefine display end feature displayis doPrecursordisplay_border display_labelend display_labelis do ... end display_borderis do ... end end OOSC Summer Semester 2004
Use of Precursor • Not necessarily the first feature statement. • May have arguments. classBinherit Aredefine my_feature end feature my_feature (args: SOME_TYPE) is do-- Something here Precursor (args) -- Something else here end end my_feature A my_feature++ B OOSC Summer Semester 2004
Inheritance and assertions Correct call: ifa1.then a1.r (...) else ... end ris C A require a1: A … ensure a1.r (…) B ris require ensure OOSC Summer Semester 2004
Assertion redeclaration rule • Redefined version may not have require or ensure. • May have nothing (assertions kept by default), or require elsenew_pre ensure thennew_post • Resulting assertions are: • original_preconditionornew_pre • original_postconditionandnew_post OOSC Summer Semester 2004
Invariant accumulation • Every class inherits all the invariant clauses of its parents. • These clauses are conceptually “and”-ed. OOSC Summer Semester 2004
Genericity vs. Inheritance Abstraction SET_OF_BOOKS Type parameterization Type parameterization LIST_OF_ LIST_OF_PEOPLE LIST_OF_BOOKS JOURNALS LINKED_LIST_OF_BOOKS Specialization OOSC Summer Semester 2004
Genericity + Inheritance 1: Polymorphic data structures classSTACK [G] feature ... item: Gis ... put (x: G) is ... end fs: STACK [FIGURE] r: RECTANGLE s: SQUARE t: TRIANGLE p: POLYGON ... fs.put (p); fs.put (t); fs.put (s); fs.put (r)fs.item.display fs (RECTANGLE) (SQUARE) (TRIANGLE) (POLYGON) OOSC Summer Semester 2004
Example hierarchy extent* display* * deferred + effective ++ redefined barycenter* * rotate … FIGURE … * * OPEN_ FIGURE CLOSED_ FIGURE perimeter* perimeter+ perimeter+ + + SEGMENT POLYLINE POLYGON ELLIPSE diagonal perimeter++ ... ... side1 TRIANGLE RECTANGLE side2 CIRCLE perimeter++ perimeter++ SQUARE OOSC Summer Semester 2004
Genericity + Inheritance 2: Constrained genericity classVECTOR [G -> NUMERIC] feature infix "+" (other: VECTOR [G]): VECTOR [G] is -- Sum of current vector and other require lower = other.lower upper = other.upper local a, b, c: G do ... See next ... end ... Other features ... end OOSC Summer Semester 2004
Constrained genericity (cont’d) • The body of infix "+": createResult.make (lower, upper) from i := lower until i > upper loop a := item (i) b := other.item (i) c := a + b-- Requires a “+” operation on G! Result.put (c, i) i := i + 1 end OOSC Summer Semester 2004
Constrained genericity (cont’d) • The body of infix "+": createResult.make (lower, upper) from i := lower until i > upper loop a := item (i) b := other.item (i) c := a + b-- Requires a “+” operation on G! Result.put (c, i) i := i + 1 end OOSC Summer Semester 2004
The solution • Declare class VECTOR as classVECTOR [G –> NUMERIC] feature ... The rest as before ... end • Class NUMERIC (from the Kernel Library) provides features infix "+", infix "*" and so on. OOSC Summer Semester 2004
Improving the solution • Make VECTOR itself a descendant of NUMERIC, effecting the corresponding features: classVECTOR [G –> NUMERIC] inherit NUMERIC feature ... The rest as before, including infix "+"... end • Then it is possible to define e.g. v: VECTOR [VECTOR [VECTOR [INTEGER]]] OOSC Summer Semester 2004
Forcing a type: the problem fs.store ("FILE_NAME") ... -- Two years later: fs.retrieve ("FILE_NAME")x := fs.item-- [1] print (x.diagonal) -- [2] But: • If x is declared of type RECTANGLE, [1] is invalid. • If x is declared of type FIGURE, [2] is invalid. OOSC Summer Semester 2004
Assignment attempt f: FIGURE r: RECTANGLE ... fs.retrieve ("FILE_NAME") f := fs.item r ?= f ifr /= Voidthenprint (r.diagonal)elseprint ("Too bad.")end OOSC Summer Semester 2004
Assignment attempt (cont’d) x ?= y with x: A • If y is attached to an object whose type conforms to A, perform normal reference assignment. • Otherwise, make x void. OOSC Summer Semester 2004
End of lecture 7 OOSC Summer Semester 2004