se.inf.ethz.ch

Download Report

Transcript se.inf.ethz.ch

Eiffel: Analysis, Design and
Programming
Bertrand Meyer
(Nadia Polikarpova)
Chair of
Software Engineering
-8-
Inheritance
2
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
3
Extending the basic notion of class
Abstraction
Inheritance
BAG_OF_
CARS
Genericity
Type parameterization
LIST_OF_
CITIES
Type parameterization
LIST_OF_
CARS
LIST_OF_
PERSONS
LINKED_LIST_
OF_CARS
Specialization
4
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)
5
Terminology
If B inherits from A (by listing A in its inherit clause):
 B is an heir of A
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
B
Reverse notions:
Ancestor
 Proper ancestor
More precise notion of instance:
 Direct instances of A
C
D
 Instances of A : the direct instances
of A and its descendants
(Other terminology: subclass, superclass, base class)
E
6
What you can do to inherited features






Effect (implicit)
Redefine
Undefine
Rename
Change export status
Select
7
Example hierarchy
center*
*
OPEN_FIGURE
SEGMENT
POLYLINE
display*
rotate*
move*
*
FIGURE
perimeter*
*
CLOSED_FIGURE
perimeter +
+
POLYGON
perimeter +
+
ELLIPSE
display +
rotate +
move +
...
TRIANGLE
perimeter ++
side1
side2
RECTANGLE
+ effective
++ redefined
perimeter ++
SQUARE
perimeter ++
CIRCLE
diagonal
* deferred
...
display +
rotate +
move +
display ++
rotate ++
move ++
8
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!
9
Redefinition 1: polygons
class POLYGON inherit
CLOSED_FIGURE
create
make
feature
vertex : ARRAY [POINT]
vertex_count : INTEGER
perimeter : REAL is
do
-- Perimeter length
vertex [i ]
vertex [i + 1]
from ... until ... loop
Result := Result + vertex [i ] . distance (vertex [i + 1])
...
end
end
invariant
vertex_count >= 3
vertex_count = vertex.count
end
10
Redefinition 2: rectangles
class RECTANGLE inherit
POLYGON
redefine
end
create
perimeter
diagonal
make
feature
diagonal, side1, side2 : REAL
side2
side1
perimeter : REAL is
-- Perimeter length
do Result := 2  (side1 + side2) end
invariant
vertex_count = 4
end
11
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
r := p
p

(POLYGON)
r
(RECTANGLE)
-- Even just after p := r !
12
Dynamic binding
What is the effect of the following (if some_test is true)?
if some_test then
p := r
else
p := t
end
x := 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 runtime form of p.
13
Without dynamic binding?
display (f : FIGURE )
do
end
if “f is a CIRCLE” then
...
elseif “f is a POLYGON” then
...
end
and similarly for all other routines!
Tedious; must be changed whenever there’s a new
figure type
14
With inheritance and associated techniques
With:
f : FIGURE
c : CIRCLE
p : POLYGON
Initialize:
if ... then
f := c
else
f := p
end
and:
.
create p.make (...)
create c make (...)
Then just use:
f.move (...)
f.rotate (...)
f display (...)
.
-- and so on for every
-- operation on f !
15
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
a
a := E
is connected a memory location.
16
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”.
17
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;
18
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
19
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
20
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 ?
21
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 */
22
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
23
Using class tables
Class Table Pointer
Class A
Integer Field
Pointer to feature f
Integer Field
Pointer to feature g
Integer Field
class A
feature
a,b,c : INTEGER
f is
do
c := a + b
g
end
g is ...
end
1. Read first field from Current
2. Add second field from Current
3. Store result in third field of Current
4. Go to the second entry in Current's
class table
24
With inheritance
class B
inherit A redefine f
feature
d: BOOLEAN
f is ...
h is ...
end
A
B
Class Table Pointer
Class B
Integer Field
Pointer to feature f
Integer Field
Pointer to feature g
Integer Field
Pointer to feature h
Boolean Field
25
Contracts and inheritance
Issue: what happens, under inheritance, to

Class invariants?

Routine preconditions and postconditions?
26
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.
27
Contracts and inheritance
a1 : A
r
A
C

…
a1.r (…)
ensure

Correct call in C:
if a1. then
a1.r (...)
end
require
D
B
-- Here a1. holds
r ++
r
require

ensure
client of
inherits from

++ redefinition
28
Assertion redeclaration rule
When redeclaring a routine, we may only:

Keep or weaken the precondition

Keep or strengthen the postcondition
29
Assertion redeclaration rule in Eiffel
A simple language rule does the trick!
Redefined version may have nothing (assertions kept by
default), or
require else new_pre
ensure then new_post
Resulting assertions are:

original_precondition or new_pre

original_postcondition and new_post
30
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)
31
A deferred feature
In e.g. LIST:
forth
require
not after
deferred
ensure
index = old index + 1
end
32
Mixing deferred and effective features
In the same class
Effective!
search (x : G)
do
-- Move to first position after current
-- where x appears, or after if none.
from until after or else item = x loop
end
end
forth
Deferred!
“Programs with holes”
33
“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
34
Deferred classes in EiffelBase
*
CONTAINER
*
*
BOX
*
FINITE
*
BOUNDED
*
*
INFINITE
*
UNBOUNDED
*
BAG
*
COUNTABLE
TRAVERSABLE
*
SET
*
*
TABLE
LINEAR
*
BILINEAR
*
INTEGER_
INTERVAL
ACTIVE
*
*
INDEXABLE
STRING
HASH_TABLE
*
*
CURSOR_
STRUCTURE
*
DISPENSER
*
STACK
*
HIERARCHICAL
…
RESIZABLE
ARRAY
*
COLLECTION
…
SEQUENCE
*
QUEUE
*
deferred
35
Deferred classes for analysis
deferred class
VAT
inherit
TANK
feature
in_valve, out_valve: VALVE
fill is
require
-- Fill the vat.
in_valve.open
out_valve.closed
deferred
ensure
in_valve.closed
out_valve.closed
is_full
end
empty, is_full, is_empty, gauge, maximum, ... [Other features] ...
invariant
is_full = (gauge >= 0.97 * maximum) and (gauge <= 1.03 * maximum)
end
36
Polymorphic data structures
fl
class
LIST [G]
feature
...
last: G is ...
extend (x: G) is ...
(SQUARE)
end
fl: LIST [FIGURE]
r: RECTANGLE
s: SQUARE
t: TRIANGLE
p: POLYGON
(TRIANGLE)
(POLYGON)
(RECTANGLE)
...
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
37
Figure hierarchy (reminder)
center*
*
OPEN_FIGURE
SEGMENT
POLYLINE
display*
rotate*
move*
*
FIGURE
perimeter*
*
CLOSED_FIGURE
perimeter +
+
POLYGON
perimeter +
+
ELLIPSE
display +
rotate +
move +
...
TRIANGLE
perimeter ++
side1
side2
RECTANGLE
+ effective
++ redefined
perimeter ++
SQUARE
perimeter ++
CIRCLE
diagonal
* deferred
...
display +
rotate +
move +
display ++
rotate ++
move ++
38
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?
x is declared of type RECTANGLE, [1] is invalid.
If x is declared of type FIGURE, [2] is invalid.
If
39
Enforcing a type: the Object Test
Optional (if omitted
just tests for void)
Expression to be
tested
Object-Test Local
.
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) RECTANGLE
else
print ("Too bad.")
end
SCOPE of the Object-Test Local
40
Earlier mechanism: assignment attempt
f : FIGURE
r : RECTANGLE
...
fl.retrieve ("FILE_NAME")
f := fl.last
r ?= f
if r /= Void then
else
end
.
print (r diagonal )
print ("Too bad.")
41
Assignment attempt
x ?= y
with
x: A
Semantics:
 If y is attached to an object whose type conforms to
A, perform normal reference assignment.

Otherwise, make x void.
42
What we have seen
 Basics
 Redefinition
 Polymorphism and dynamic binding
 Inheritance and contracts
 Deferred classes
 Polymorphic containers
43
Topics for today
 Inheritance and genericity: constrained genericity
 Multiple inheritance
 Non-conforming inheritance
 Covariance and anchored types
44
Inheritance + Genericity
Unconstrained genericity
LIST [G]
e.g. LIST [INTEGER], LIST [PERSON]
Constrained genericity
HASH_TABLE [G, H ―> HASHABLE ]
VECTOR [G ―> NUMERIC ]
45
Constrained genericity
class VECTOR [G
] feature
plus alias "+" (other : VECTOR [G]): VECTOR [G]
-- Sum of current vector and other.
require
local
do
end
lower = other.lower
upper = other.upper
a, b, c: G
... See next ...
end
... Other features ...
46
Adding two vectors
u
2
i1
a
+
v
=
w
+
b
=
c
47
Constrained genericity
Body of plus alias "+":
create Result.make (lower, upper)
from
until
loop
end
i := lower
i > upper
a := item (i )
b := other.item (i )
c := a + b
-- Requires “+” operation on G!
Result.put (c, i )
i := i + 1
48
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.
49
Improving the solution
Make VECTOR itself a descendant of NUMERIC,
effecting the corresponding features:
class VECTOR [G –> NUMERIC ] inherit
NUMERIC
feature
... Rest as before, including infix "+"...
end
Then it is possible to define
v : VECTOR [INTEGER ]
vv : VECTOR [VECTOR [INTEGER ]]
vvv : VECTOR [VECTOR [VECTOR [INTEGER ]]]
50
In the end...
Genericity is always constrained because
LIST [G]
is just an abbreviation of
LIST [G -> ANY]
51
Combining abstractions
Given the classes

TRAIN_CAR, RESTAURANT
how would you implement a DINER?
52
Examples of multiple inheritance
Combining separate abstractions:
Restaurant, train car
 Calculator, watch
 Plane, asset
 Home, vehicle
 Tram, bus

53
Composite figures
54
Multiple inheritance: Composite figures
Simple figures
A composite figure
55
Defining the notion of composite figure
center
display
hide
rotate
move
…
LIST
[FIGURE ]
FIGURE
count
put
remove
…
COMPOSITE_
FIGURE
56
In the overall structure
LIST
[FIGURE ]
FIGURE
OPEN_
FIGURE
SEGMENT
POLYLINE
TRIANGLE
CLOSED_
FIGURE
perimeter*
POLYGON
ELLIPSE
perimeter+
perimeter+
diagonal
COMPOSITE_
FIGURE
RECTANGLE
CIRCLE
perimeter++ perimeter++
SQUARE
perimeter++
57
A composite figure as a list
before
after
item
Cursor
forth
58
Composite figures
class COMPOSITE_FIGURE inherit
FIGURE
LIST [FIGURE]
feature
display
do
-- Display each constituent figure in turn.
from start until after loop
item.display
end
end
forth
Requires dynamic
binding
end
... Similarly for move, rotate etc. ...
59
Multiple inheritance: Combining abstractions
<, <=,
>, >=,
…
NUMERIC
COMPARABLE
+, –,
, /
…
(commutative
ring)
(total order
relation)
INTEGER
REAL
STRING
COMPLEX
61
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
62
Multiple inheritance: Combining abstractions
<, <=,
>, >=,
…
NUMERIC
COMPARABLE
+, –,
, /
…
(commutative
ring)
(total order
relation)
INTEGER
REAL
STRING
COMPLEX
63
How do we write COMPARABLE?
deferred class COMPARABLE [G ] feature
less alias "<" (x : COMPARABLE [G ]): BOOLEAN
deferred
end
less_equal alias "<=" (x : COMPARABLE [G ]): BOOLEAN
do
Result := Current < x or Current ~ x
end
greater alias ">" (x : COMPARABLE [G ]): BOOLEAN
do Result := x < Current end
end
greater_equal alias ">=" (x : COMPARABLE [G ]): BOOLEAN
do Result := x <= Current end
64
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
65
Multiple inheritance: Name clashes
f
B
A
C
f
?
66
Resolving name clashes
f
B
A
f
rename f as A_f
C
A_f, f
67
Consequences of renaming
a1 : A
b1 : B
c1 : C
f
B
A
f
...
c1.f
c1.A_f
rename f as A_f
C
A_f, f
a1.f
b1.f
Invalid:
.A_f
 b1.A_f
 a1
68
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)
69
Feature merging
f*
A
f*
B
C
f+
D
 Deferred
+ Effective
70
Feature merging: with different names
class
D
inherit
A
g*
B
C
f*
h+
rename
g as f
end
B
C
A
rename
h as f
end
feature
...
end
g
f
D
h
f
 Deferred
+ Effective
Renaming
71
Feature merging: effective features
f+
A
f+
f --
B
C
f+
f -D
 Deferred
+ Effective
-- Undefine
72
Undefinition
deferred class
T
inherit
S
undefine v end
feature
...
end
73
Merging through undefinition
f+
A
f+
B
C
f+
class
D
inherit
A
undefine f end
B
C
undefine f end
feature
...
end
f --
f -D
 Deferred
+ Effective
-- Undefine
74
Merging effective features with different names
f+
A
g+
h+
B
C
class
D
inherit
A
B
C
g
undefine f end
rename
g as f
undefine f
end
rename
h as f
end
feature ... end
f --
f --
f
h
f
D
75
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
76
A special case of multiple inheritance
UNIVERSITY
_MEMBER
TEACHER
id
STUDENT
??
??
ASSISTANT
????
This is a case of repeated inheritance
78
Indirect and direct repeated inheritance
A
A
C
B
D
D
79
Multiple is also repeated inheritance
A typical case:
copy ++
is_equal ++
ANY
copy
is_equal
C
LIST
D
copy
C_copy
is_equal
C_is_equal
??
80
Sharing and replication
A
g
g_b
f
g
C
B
g
g_c
D
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.
81
The need for select
A potential ambiguity arises because of polymorphism and
dynamic binding:
copy
ANY
a1 : ANY
d1 : D
…
a1 := d1
a.copy (…)
copy ++
is_equal
C
LIST
is_equal ++
copy
C_copy
is_equal
C_is_equal
D
82
Removing the ambiguity
class
D
inherit
LIST [T ]
select
end
C
copy,
is_equal
rename
copy as C_copy,
is_equal as C_is_equal,
end
...
83
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.
84
Another application of renaming
Provide locally better adapted terminology.
Example: child (TREE ); subwindow (WINDOW)
85
Non-conforming inheritance
class ARRAY [G] feature ...
lower, upper: INTEGER
resize (l, u: INTEGER)
ensure lower = l; upper = u
end
class ARRAYED_LIST [G]
inherit
LIST [G]
ARRAY [G]
...
invariant
starts_from_1: lower = 1
end
LIST
ARRAY
ARRAYED_LIST
a: ARRAY [INTEGER]; l: ARRAYED_LIST [INTEGER]
...
a := l
a.resize (-10, 10)
Class invariant
violation
91
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!
92
Non-conforming inheritance
class ARRAYED_LIST [G]
inherit
LIST [G]
Non-conforming
inherit {NONE}
inheritance
ARRAY [G]
...
invariant
end
LIST
ARRAY
starts_from_1: lower = 1
a: ARRAY [INTEGER];
l: ARRAYED_LIST [INTEGER]
ARRAYED_LIST
...
Not allowed
a := l
a.resize (-10, 10)
93
No need for select
Potential ambiguity is resolved is favor of conforming
parent:
count
FINITE
f : FINITE [...]
al: ARRAYED_LIST [...]
…
LIST
ARRAY
f := al
print (f.count)
Version from
count
capacity
ARRAYED_LIST
LIST
94
Covariance
class LIST [G] feature
…
end
LIST
CURSOR
LINKED_LIST
LINKED_CURSOR
cursor: CURSOR
go_to (c: CURSOR) is do … end
class LINKED_LIST [G] inherit
LIST [G]
redefine cursor, go_to, ... end
feature
cursor: LINKED_CURSOR
go_to (c: LINKED_CURSOR) is do … end
…
end
95
Anchored types
class LIST [G] feature
…
end
cursor: CURSOR
go_to (c: like cursor) is do … end
class LINKED_LIST [G] inherit
LIST [G]
redefine cursor, ... end
feature
cursor: LINKED_CURSOR
-- No need to redefine `go_to’
…
end
96
Semantics of anchored types
In class C :
x: SOME_TYPE
y: 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.
97
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
98
The problem with covariance
list: LIST [...]
linked_list: LINKED_LIST [...]
class LIST feature
end
end
c: CURSOR
cursor: CURSOR
go_to (c: like cursor) is do …
…
class LINKED_LIST inherit
…
list := linked_list
list.go_to (c)
LIST
redefine cursor, ... end
feature
cursor: LINKED_CURSOR
-- No need to redefine `go_to’
…
end
Catcall!
99
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
100
Catcall cases
 Covariant redefinition of arguments
•
Non-generic case
•
Generic case
 Descendant hiding (in earlier versions of Eiffel)
101
Covariant redefinition: non-generic case
class ANIMAL
feature
eat (a_food: FOOD)
deferred
end
end
class WOLF
inherit ANIMAL
redefine eat end
feature
eat (a_meat: MEAT)
do …
end
end
ANIMAL
WOLF
FOOD
MEAT
GRASS
102
Covariant redefinition: non-generic case
animal: ANIMAL
wolf: WOLF
food: FOOD
grass: GRASS
create wolf
create grass
animal := wolf
food := grass
animal.eat (grass)
ANIMAL
WOLF
FOOD
MEAT
GRASS
103
Covariant redefinition: generic case
animal_list: LINKED_LIST [ANIMAL]
sheep_list: LINKED_LIST [SHEEP]
sheep: SHEEP
wolf: WOLF
sheep_list.extend (sheep)
animal_list := sheep_list
animal_list.extend (wolf)
ANIMAL
SHEEP
WOLF
104
Covariant redefinition: generic case
class LINKED_LIST [ANY]
feature
extend (v: ANY) do … end
end
class LINKED_LIST [SHEEP]
feature
extend (v: SHEEP) do … end
end
class LINKED_LIST [WOLF]
feature
extend (v: WOLF) do … end
end
105
Descendant hiding
class RECTANGLE
inherit POLYGON
export {NONE}
end
Now: not allowed
add_vertex
POLYGON
…
invariant
end
vertex_count = 4
RECTANGLE
r: RECTANGLE; p: POLYGON
...
p := r
p.add_vertex (...)
Earlier: catcall!
106
Descendant hiding: solution 1
class RECTANGLE
inherit {NONE} POLYGON
export {NONE}
end
add_vertex
POLYGON
…
invariant
end
Nonconforming
inheritance
vertex_count = 4
RECTANGLE
r: RECTANGLE; p: POLYGON
...
p := r
p.add_vertex (...)
Not allowed
107
Descendant hiding: solution 2
class POLYGON feature ...
variable_vertex_count: BOOLEAN
do Result := True end
add_vertex (...)
end
require variable_vertex_count
do ... end
class RECTANGLE inherit POLYGON
redefine variable_vertex_count end
feature ...
variable_vertex_count: BOOLEAN = False
end
POLYGON
RECTANGLE
p: POLYGON
...
if p.variable_vertex_count then
p.add_vertex (...)
end
108
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

109
Inheritance: summary (2)
Polymorphic containers + object test: flexible and typesafe

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!)

110