eiffel: analysis, design and programming bertrand meyer (nadia polikarpova )

103
Eiffel: Analysis, Design and Programming Bertrand Meyer (Nadia Polikarpova) Chair of Software Engineering

Upload: alka

Post on 11-Feb-2016

44 views

Category:

Documents


0 download

DESCRIPTION

Eiffel: Analysis, Design and Programming Bertrand Meyer (Nadia Polikarpova ). Chair of Software Engineering. - 8 - Inheritance. Overview. Basics Redefinition Polymorphism and dynamic binding Inheritance and contracts Deferred classes Polymorphic containers - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

Eiffel: Analysis, Design and Programming

Bertrand Meyer(Nadia Polikarpova)

Chair ofSoftware Engineering

Page 2: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

2

- 8 -

Inheritance

Page 3: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

3

Overview Basics Redefinition Polymorphism and dynamic binding Inheritance and contracts Deferred classes Polymorphic containers Inheritance and genericity: constrained genericity Multiple inheritance Non-conforming inheritance Covariance and anchored types

Page 4: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

4

Extending the basic notion of class

LIST_OF_CARS

BAG_OF_CARS

LINKED_LIST_OF_CARS

LIST_OF_CITIES

LIST_OF_PERSONS

Abstraction

Specialization

Type parameterization

Type parameterization

Genericity

Inheritance

Page 5: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

5

Inheritance basics

Principle:Describe a new class as extension or specialization of an existing class

(or several with multiple inheritance)

If B inherits from A :

As modules: all the services of A are available in B

(possibly with a different implementation)

As types: whenever an instance of A is required, an instance of B will be acceptable

(“is-a” relationship)

Page 6: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

6

TerminologyIf B inherits from A (by listing A in its inherit clause):

B is an heir of A A is a parent of B

For a class A:The descendants of A are A itself and (recursively) the descendants of A ’s heirs Proper descendants exclude A itself

Reverse notions:Ancestor Proper ancestor

More precise notion of instance: Direct instances of A Instances of A : the direct instances of A and its descendants

(Other terminology: subclass, superclass, base class)

B

A

C D

E

Page 7: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

7

What you can do to inherited features

Effect (implicit) Redefine Undefine Rename Change export status Select

Page 8: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

8

Example hierarchycenter*

perimeter*

perimeter +

...

...

* deferred+ effective++ redefined

display*rotate*move*

*FIGURE

*OPEN_FIGURE *CLOSED_FIGURE

SEGMENT POLYLINE +ELLIPSE

CIRCLE

+POLYGON

TRIANGLE

SQUARE

RECTANGLE

perimeter +

display +rotate +move +

perimeter ++

side1

side2

diagonalperimeter ++

display +rotate +move +

perimeter ++

display ++

rotate ++

move ++

Page 9: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

9

Redefinition

Class may redefine (“override”) inherited features

Redefinition is explicit In line with Uniform Access principle, may

redefine inherited function into attribute

Not the other way around!

Page 10: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

10

Redefinition 1: polygonsclass POLYGON inherit

CLOSED_FIGUREcreate

makefeature

vertex : ARRAY [POINT]vertex_count : INTEGER perimeter : REAL is

-- Perimeter lengthdo from ... until ... loop Result := Result + vertex [i ] . distance (vertex [i +

1]) ... end

endinvariant

vertex_count >= 3vertex_count = vertex.count

end

vertex [i ]

vertex [i + 1]

Page 11: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

11

Redefinition 2: rectangles

class RECTANGLE inheritPOLYGONredefine

perimeter end

createmake

featurediagonal, side1, side2 : REALperimeter : REAL is

-- Perimeter lengthdo Result := 2 (side1 + side2) end

invariantvertex_count = 4

end

side1

side2diagonal

Page 12: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

12

Inheritance, typing and polymorphism

(POLYGON)

(RECTANGLE)

p

r

Assume: p : POLYGON ; r : RECTANGLE ; t : TRIANGLE x : REAL

Permitted: x := p.perimeterx := r.perimeterx := r.diagonalp := r

NOT permitted:

x := p.diagonal -- Even just after p := r !

r := p

Page 13: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

13

Dynamic binding

What is the effect of the following (if some_test is true)?

if some_test thenp := r

elsep := t

endx := p.perimeter

Redefinition: A class may change an inherited feature, as with POLYGON redefining perimeter.Polymorphism: p may have different forms at run-time.Dynamic binding: Effect of p.perimeter depends on run-time form of p.

Page 14: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

14

Without dynamic binding?

display (f : FIGURE )do

if “f is a CIRCLE” then ...

elseif “f is a POLYGON” then...

endend

and similarly for all other routines!

Tedious; must be changed whenever there’s a new figure type

Page 15: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

15

With inheritance and associated techniques

With:

Initialize:

and:

Then just use:

f : FIGUREc : CIRCLEp : POLYGON

create c.make (...)create p.make (...)

if ... then f := c

else f := p

end

f.move (...)f.rotate (...)f.display (...)

-- and so on for every-- operation on f !

Page 16: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

16

Binding

Binding is the process in which A routine invocation f (a), x.f (a) is connected to

code that is executed Accessing or writing to a variable

aa := Eis connected a memory location.

Page 17: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

17

Static vs. dynamic binding

If binding is done at compile time, this is called “Static Binding” using “Static Linking”.

If binding is done at program load time, this is called “Static Binding” using “Dynamic Linking”.

If binding is done at runtime this is called “Dynamic Binding”.

Page 18: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

18

Static Binding in C

In the .h header file:

extern int foo (arg c);extern float my_variable;

In the .c file:

int foo (arg c);float my_variable;

Page 19: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

19

Execution of a call in C

On the caller side: Push the arguments on the stack Push the current PC + 1 on the stack (return

address) Jump to the code to execute

This is “filled out” during linking/binding Clean the stack

Page 20: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

20

Execution of a call in C (cont.)

On the callee side: Add some extra memory on the stack for the local

variables Initialize the local variables (if necessary) Execute the implementation of the routine Read the return address from the stack Jump to the return address

Page 21: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

21

Dynamic Binding in non-OO

Dynamic binding is not exclusive for object-orientation:

Lisp (1958) Forth (1970) - a mixture called “Threaded Code” C (1970) - Why ?

Page 22: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

22

Dynamic Binding in C#include <stdio.h>void hello () { printf ("Hello\n");}

void world () { printf ("World\n");}

int main (int argc, char **argv) { void (*func)(void);

if (argc > 1) func = hello; else func = world;

func (); /* Dynamic Binding */}

Page 23: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

23

Dynamic Binding and OO

We need dynamic binding in object-orientation

Identifiers used in program text are relative to the current object:

Attributes are relative to Current Routines may be redefined in subclasses

Page 24: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

24

Using class tablesClass Table Pointer

Integer FieldInteger FieldInteger Field

Class APointer to feature fPointer to feature g

1. Read first field from Current2. Add second field from Current3. Store result in third field of Current4. Go to the second entry in Current'sclass table

class Afeature

a,b,c : INTEGERf is

doc := a + bg

endg is ...

end

Page 25: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

25

With inheritance

Class Table PointerInteger FieldInteger FieldInteger Field

Class BPointer to feature fPointer to feature g

Boolean FieldPointer to feature h

A

B

class Binherit A redefine ffeature

d: BOOLEANf is ...h is ...

end

Page 26: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

26

Contracts and inheritance

Issue: what happens, under inheritance, to

Class invariants?

Routine preconditions and postconditions?

Page 27: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

27

Invariants

Invariant Inheritance rule: The invariant of a class automatically includes

the invariant clauses from all its parents, “and”-ed.

Accumulated result visible in flat and interface forms.

Page 28: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

28

Contracts and inheritance

rrequire

ensure

rrequire

ensure

a1 : Aa1.r (…)…

Correct call in C: if a1. then a1.r (...) -- Here a1. holds end

r ++

C A

D B

client of inherits from++ redefinition

Page 29: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

29

Assertion redeclaration rule

When redeclaring a routine, we may only:

Keep or weaken the precondition

Keep or strengthen the postcondition

Page 30: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

30

A simple language rule does the trick!

Redefined version may have nothing (assertions kept by default), or

require else new_preensure then new_post

Resulting assertions are: original_precondition or new_pre

original_postcondition and new_post

Assertion redeclaration rule in Eiffel

Page 31: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

31

The role of deferred classes

Express abstract concepts independently of implementation

Express common elements of various implementations

Terminology: Effective = non-deferred(i.e. fully implemented)

Page 32: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

32

In e.g. LIST:

forth

deferred

end

A deferred feature

ensureindex = old index + 1

requirenot after

Page 33: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

33

Deferred!

In the same class

search (x : G)-- Move to first position after current

-- where x appears, or after if none.

do from until after or else item = x loop

forth endend

“Programs with holes”

Mixing deferred and effective features

Effective!

Page 34: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

34

“Don’t call us, we’ll call you!”

A powerful form of reuse: The reusable element defines a general scheme Specific cases fill in the holes in that scheme

Combine reuse with adaptation

Page 35: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

35

Deferred classes in EiffelBase

CONTAINER*BOX* COLLECTION* TRAVERSABLE*

FINITE* INFINITE*

BOUNDED* UNBOUNDED* COUNTABLE*

RESIZABLE*

BAG* SET* HIERARCHICAL* LINEAR*

TABLE* ACTIVE* INTEGER_ INTERVAL

* BILINEAR*

INDEXABLE* CURSOR_ STRUCTURE

* DISPENSER* SEQUENCE*

ARRAY STRING HASH_TABLE STACK* QUEUE*

… …

* deferred

Page 36: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

36

deferred classVAT

inheritTANK

featurein_valve, out_valve: VALVEfill is

-- Fill the vat.require

in_valve.openout_valve.closed

deferredensure

in_valve.closedout_valve.closedis_full

endempty, is_full, is_empty, gauge, maximum, ... [Other features] ...

invariantis_full = (gauge >= 0.97 * maximum)  and  (gauge <= 1.03 *

maximum)end

Deferred classes for analysis

Page 37: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

37

Polymorphic data structures

classLIST [G] feature

...last: G is ...extend (x: G) is ...

end

fl: LIST [FIGURE]r: RECTANGLEs: SQUAREt: TRIANGLEp: POLYGON...fl.extend (p); fl.extend (t); fl.extend (s); fl.extend (r)

from fl.start until fl.after loop fl.item.display; fl.forth end

(SQUARE)

(RECTANGLE)

(TRIANGLE)

(POLYGON)

fl

Page 38: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

38

Figure hierarchy (reminder)center*

perimeter*

perimeter +

...

...

* deferred+ effective++ redefined

display*rotate*move*

*FIGURE

*OPEN_FIGURE *CLOSED_FIGURE

SEGMENT POLYLINE +ELLIPSE

CIRCLE

+POLYGON

TRIANGLE

SQUARE

RECTANGLE

perimeter +

display +rotate +move +

perimeter ++

side1

side2

diagonalperimeter ++

display +rotate +move +

perimeter ++

display ++

rotate ++

move ++

Page 39: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

39

Enforcing a type: the problem

fl.store ("FILE_NAME")...

-- Two years later:fl := retrieved ("FILE_NAME“) x := fl.last -- [1]print (x.diagonal ) -- [2]

What’s wrong with this?

If x is declared of type RECTANGLE, [1] is invalid.If x is declared of type FIGURE, [2] is invalid.

Page 40: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

40

Object-Test Local

Enforcing a type: the Object Test

if attached {RECTANGLE } fl.last as r then

print (r.diagonal )… Do anything else with r, guaranteed to be

non-void… and of dynamic type (descendant of)

RECTANGLEelse

print ("Too bad.")end

Expression to be tested

SCOPE of the Object-Test Local

Optional (if omitted just tests for void)

Page 41: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

41

Earlier mechanism: assignment attempt

f : FIGUREr : RECTANGLE...fl.retrieve ("FILE_NAME")f := fl.last

r ?= f

if r /= Void thenprint (r.diagonal )

elseprint ("Too bad.")

end

Page 42: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

42

Assignment attempt

x ?= ywith

x : A

Semantics: If y is attached to an object whose type conforms

to A, perform normal reference assignment.

Otherwise, make x void.

Page 43: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

43

What we have seen Basics Redefinition Polymorphism and dynamic binding Inheritance and contracts Deferred classes Polymorphic containers

Page 44: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

44

Topics for today Inheritance and genericity: constrained genericity Multiple inheritance Non-conforming inheritance Covariance and anchored types

Page 45: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

45

Inheritance + Genericity

Unconstrained genericityLIST [G]

e.g. LIST [INTEGER], LIST [PERSON]

Constrained genericityHASH_TABLE [G, H ―> HASHABLE ]VECTOR [G ―> NUMERIC ]

Page 46: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

46

Constrained genericity

class VECTOR [G ] feature plus alias "+" (other : VECTOR [G]): VECTOR [G]

-- Sum of current vector and other.require

lower = other.lowerupper = other.upper

locala, b, c: G

do... See next ...

end... Other features ...

end

Page 47: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

47

Adding two vectors

i a b c=+

+ =u v w

12

Page 48: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

48

Constrained genericity

Body of plus alias "+":

create Result.make (lower, upper)from

i := lower until

i > upper loop

a := item (i )b := other.item (i )c := a + b -- Requires “+” operation on G!

Result.put (c, i )i := i + 1

end

Page 49: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

49

The solution

Declare class VECTOR as

class VECTOR [G –> NUMERIC ] feature... The rest as before ...

end

Class NUMERIC (from the Kernel Library) provides features plus alias "+", minus alias "-"and so on.

Page 50: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

50

Improving the solution

Make VECTOR itself a descendant of NUMERIC,effecting the corresponding features:

class VECTOR [G –> NUMERIC ] inheritNUMERIC

feature... Rest as before, including infix "+"...

endThen it is possible to define

v : VECTOR [INTEGER ]vv : VECTOR [VECTOR [INTEGER ]]vvv : VECTOR [VECTOR [VECTOR [INTEGER ]]]

Page 51: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

51

In the end...

Genericity is always constrained becauseLIST [G]

is just an abbreviation ofLIST [G -> ANY]

Page 52: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

52

Combining abstractions

Given the classes TRAIN_CAR, RESTAURANT

how would you implement a DINER?

Page 53: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

53

Examples of multiple inheritance

Combining separate abstractions:

Restaurant, train car Calculator, watch Plane, asset Home, vehicle Tram, bus

Page 54: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

54

Composite figures

Page 55: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

55

Multiple inheritance: Composite figures

A composite figure

Simple figures

Page 56: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

56

Defining the notion of composite figure

COMPOSITE_FIGURE

centerdisplayhiderotatemove…

countputremove…

FIGURELIST

[FIGURE ]

Page 57: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

57

In the overall structure

COMPOSITE_FIGURE

FIGURE LIST [FIGURE ]

OPEN_FIGURE

CLOSED_FIGURE

SEGMENT POLYLINE POLYGON ELLIPSE

RECTANGLE

SQUARE

CIRCLETRIANGLE

perimeter+

perimeter*

perimeter++

diagonal

perimeter++

perimeter++

perimeter+

Page 58: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

58

A composite figure as a list

Cursor

item

forth

afterbefore

Page 59: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

59

Composite figures

class COMPOSITE_FIGURE inheritFIGURELIST [FIGURE]

featuredisplay

-- Display each constituent figure in turn.do

from start until after loop

item.display

forth endend... Similarly for move, rotate etc. ...

end

Requires dynamic binding

Page 60: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

61

Multiple inheritance: Combining abstractions

COMPARABLE NUMERIC

STRING COMPLEX

INTEGER

REAL

<, <=, >, >=, …

+, –, , / …(total order relation)

(commutative ring)

Page 61: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

62

The Java-C# solution

No multiple inheritance for classes

“Interfaces”: specification only (but no contracts) Similar to completely deferred classes (with no

effective feature)

A class may inherit from: At most one class Any number of interfaces

Page 62: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

63

Multiple inheritance: Combining abstractions

COMPARABLE NUMERIC

STRING COMPLEX

INTEGER

REAL

<, <=, >, >=, …

+, –, , / …(total order relation)

(commutative ring)

Page 63: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

64

How do we write COMPARABLE?

deferred class COMPARABLE [G ] feature

end

less alias "<" (x : COMPARABLE [G ]): BOOLEANdeferredend

less_equal alias "<=" (x : COMPARABLE [G ]): BOOLEAN

doResult := Current < x or Current ~ x

endgreater alias ">" (x : COMPARABLE [G ]): BOOLEAN

do Result := x < Current endgreater_equal alias ">=" (x : COMPARABLE [G ]): BOOLEAN

do Result := x <= Current end

Page 64: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

65

Lessons from this example

Typical example of program with holes

We need the full spectrum from fully abstract (fully deferred) to fully implemented classes

Multiple inheritance is there to help us combine abstractions

Page 65: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

66

Multiple inheritance: Name clashes

f

C

f A B

?

Page 66: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

67

Resolving name clashes

f

rename f as A_f

C

f A B

A_f, f

Page 67: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

68

Consequences of renaming

a1 : Ab1 : Bc1 : C...c1.fc1.A_fa1.fb1.f

rename f as A_f

C

f A B

A_f, f

f

Invalid: a1.A_f b1.A_f

Page 68: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

69

Are all name clashes bad?

A name clash must be removed unless it is: Under repeated inheritance (i.e. not a real clash)

Between features of which at most one is effective(i.e. others are deferred)

Page 69: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

70

Feature merging

A B C

D

f +f * f *

Deferred+ Effective

Page 70: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

71

Feature merging: with different names

A B C

D

h +g * f *

Deferred+ Effective Renaming

g f h f

classD

inheritA

rename

g as f

endBC

rename

h as f

end

feature...

end

Page 71: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

72

Feature merging: effective features

A B C

D

f +

f + f +

Deferred+ Effective-- Undefine

f --f --

Page 72: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

73

Undefinition

deferred classT

inheritS

undefine v endfeature

...end

Page 73: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

74

Merging through undefinition

classD

inheritA

undefine f endBC

undefine f endfeature

...end

A B C

D

f +

f + f +

f --f --

Deferred+ Effective-- Undefine

Page 74: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

75

Merging effective features with different names

A B C

D

h +

f + g +

f --

f --

classD

inheritA

undefine f endB

rename g

as f undefine

f end

Crename

h as f

end

feature ... end

h f

g f

Page 75: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

76

Acceptable name clashes

If inherited features have all the same names, there is no harmful name clash if:

They all have compatible signatures At most one of them is effective

Semantics of such a case: Merge all features into one If there is an effective feature, it imposes its

implementation

Page 76: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

78

A special case of multiple inheritance

TEACHER STUDENT

ASSISTANT

UNIVERSITY_MEMBER id

This is a case of repeated inheritance

????

????

Page 77: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

79

Indirect and direct repeated inheritance

A

D

B C

A

D

Page 78: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

80

Multiple is also repeated inheritance

A typical case:

copy ++

is_equal ++

copyis_equal

??

copy C_copyis_equal C_is_equal

CLIST

D

ANY

Page 79: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

81

Sharing and replication

Features such as f, not renamed along any of the inheritance paths, will be shared.Features such as g, inherited under different names, will be replicated.

A

B C

D

fg

g g_b

g g_c

Page 80: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

82

The need for select

A potential ambiguity arises because of polymorphism and dynamic binding:

a1 : ANYd1 : D

a1 := d1a.copy (…)

copy ++

is_equal ++

copy C_copyis_equal C_is_equal

CLIST

D

copyis_equal ANY

Page 81: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

83

Removing the ambiguity

classD

inheritLIST [T ]

selectcopy, is_equal

end

Crename

copy as C_copy, is_equal as C_is_equal,

...end

Page 82: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

84

When is a name clash acceptable?

(Between n features of a class, all with the same name, immediate or inherited.)

They must all have compatible signatures.

If more than one is effective, they must all come from a common ancestor feature under repeated inheritance.

Page 83: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

85

Another application of renaming

Provide locally better adapted terminology.

Example: child (TREE ); subwindow (WINDOW)

Page 84: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

91

Non-conforming inheritanceclass ARRAY [G] feature ...

lower, upper: INTEGERresize (l, u: INTEGER)

ensure lower = l; upper = uend

class ARRAYED_LIST [G] inherit

LIST [G]ARRAY [G]

...invariant starts_from_1: lower = 1end

a: ARRAY [INTEGER]; l: ARRAYED_LIST [INTEGER]...a := la.resize (-10, 10)

ARRAYED_LIST

LIST ARRAY

Class invariant violation

Page 85: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

92

Inheritance basics: extended

If B inherits from A : As modules: all the services of A are available in B

(possibly with a different implementation)

As types: whenever an instance of A is required, an instance of B will be acceptable

(“is-a” relationship)

If B inherits from A in a non-conforming way: As modules: all the services of A are available in B

(possibly with a different implementation)

No relationship between types!

Page 86: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

93

Non-conforming inheritance

class ARRAYED_LIST [G] inherit

LIST [G]inherit {NONE}

ARRAY [G]...invariant starts_from_1: lower = 1end

a: ARRAY [INTEGER]; l: ARRAYED_LIST [INTEGER]...a := la.resize (-10, 10)

ARRAYED_LIST

LIST ARRAYNon-

conforming inheritance

Not allowed

Page 87: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

94

No need for select

count

count capacity

ARRAYLIST

ARRAYED_LIST

FINITE

Potential ambiguity is resolved is favor of conforming parent:

f : FINITE [...]al: ARRAYED_LIST [...]

f := alprint (f.count)

Version from LIST

Page 88: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

95

Covariance

class LIST [G] feature cursor: CURSOR go_to (c: CURSOR) is do … end

…end

class LINKED_LIST [G] inherit LIST [G] redefine cursor, go_to, ... endfeature cursor: LINKED_CURSOR go_to (c: LINKED_CURSOR) is do … end …end

LINKED_LIST

LIST

LINKED_CURSOR

CURSOR

Page 89: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

96

Anchored types

class LIST [G] feature cursor: CURSOR go_to (c: like cursor) is do … end

…end

class LINKED_LIST [G] inherit LIST [G] redefine cursor, ... endfeature cursor: LINKED_CURSOR

-- No need to redefine `go_to’ …

end

Page 90: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

97

Semantics of anchored types

In class C :

x: SOME_TYPEy: like x

In class C, y is treated exactly as with y: SOME_TYPE

In a descendant D of C, if x has been redeclared to some other type, y will be treated as it if also had that type.

Page 91: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

98

Type redefinition rule

Eiffel: covariant redefinition of result(may change type to a descendant of the original

type) covariant redefinition of arguments

Traditional notion of subtyping : covariant redefinition of result contravariant redefinition of arguments(may change type to an ancestor of the original

type)

Contravariant redefinition: safe but useless

Page 92: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

99

The problem with covariance

list: LIST [...]linked_list: LINKED_LIST [...]

c: CURSOR

…list := linked_listlist.go_to (c)

class LIST feature cursor: CURSOR go_to (c: like cursor) is do … end

…end

class LINKED_LIST inherit LIST redefine cursor, ... endfeature cursor: LINKED_CURSOR

-- No need to redefine `go_to’ …

end

Catcall!

Page 93: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

100

CAT calls CAT stands for Changing Availability or Type A routine is a CAT if some redefinition changes its

export status or the type of any of its arguments A call is a catcall if some redefinition of the routine

would make it invalid because of a change of export status or argument type

Page 94: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

101

Catcall cases Covariant redefinition of arguments

• Non-generic case• Generic case

Descendant hiding (in earlier versions of Eiffel)

Page 95: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

102

Covariant redefinition: non-generic caseclass ANIMAL feature

eat (a_food: FOOD) deferredend

end

class WOLFinherit ANIMAL

redefine eat endfeature

eat (a_meat: MEAT) do … end

end

WOLF

ANIMAL

FOOD

MEAT GRASS

Page 96: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

103

animal: ANIMALwolf: WOLFfood: FOODgrass: GRASS

create wolfcreate grassanimal := wolffood := grassanimal.eat (grass)

Covariant redefinition: non-generic case

WOLF

ANIMAL

FOOD

MEAT GRASS

Page 97: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

104

animal_list: LINKED_LIST [ANIMAL]sheep_list: LINKED_LIST [SHEEP]sheep: SHEEPwolf: WOLF

sheep_list.extend (sheep)animal_list := sheep_listanimal_list.extend (wolf)

Covariant redefinition: generic case

WOLF

ANIMAL

SHEEP

Page 98: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

105

class LINKED_LIST [ANY]feature

extend (v: ANY) do … endend

class LINKED_LIST [SHEEP]feature

extend (v: SHEEP) do … endend

class LINKED_LIST [WOLF]feature

extend (v: WOLF) do … endend

Covariant redefinition: generic case

Page 99: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

106

class RECTANGLE inherit POLYGON

export {NONE} add_vertex

end…invariant

vertex_count = 4end

r: RECTANGLE; p: POLYGON...p := rp.add_vertex (...)

Descendant hiding

RECTANGLE

POLYGON

Earlier: catcall!

Now: not allowed

Page 100: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

107

class RECTANGLE inherit {NONE} POLYGON

export {NONE} add_vertex

end…invariant

vertex_count = 4end

r: RECTANGLE; p: POLYGON...p := rp.add_vertex (...)

Descendant hiding: solution 1

RECTANGLE

POLYGON

Not allowed

Nonconforming inheritance

Page 101: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

108

class POLYGON feature ...variable_vertex_count: BOOLEAN

do Result := True endadd_vertex (...)

require variable_vertex_countdo ... end

end

class RECTANGLE inherit POLYGONredefine variable_vertex_count end

feature ... variable_vertex_count: BOOLEAN = False

end

p: POLYGON...if p.variable_vertex_count then

p.add_vertex (...)end

Descendant hiding: solution 2

RECTANGLE

POLYGON

Page 102: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

109

Inheritance: summary (1)

Type mechanism: lets you organize our data abstractions into taxonomies

Module mechanism: lets you build new classes as extensions of existing ones

Polymorphism: flexibility with type safety Dynamic binding: automatic adaptation of

operation to target, for more modular software architectures

Contracts inheritance: ensures properties to clients in presence of polymorphism

Deferred classes: a mechanism to express properties of abstract concepts

Page 103: Eiffel: Analysis, Design and Programming Bertrand  Meyer (Nadia  Polikarpova )

110

Inheritance: summary (2)

Polymorphic containers + object test: flexible and type-safe

Constrained genericity: allows calling specific features on expression of parameter types

Multiple inheritance: powerful way of combining abstractions

Non-conforming inheritance: a way to express code reuse without subtyping

Catcalls: result from covariant redefinition of argument types (even more tricky with genericity!)