Principles of Object-Oriented Software Development

Principles of Object-Oriented
Software Development
Polymorphism
Polymorphism
Introduction
Abstract inheritance
The subtype relation
Flavors of polymorphism
Type abstraction
Existential types -- hiding
Self-reference
Summary
Q/A
Literature
Polymorphism
•
•
•
•
abstract inheritance
subtypes
type abstraction
self-reference
Additional keywords and phrases:
exceptions, type calculi, parametric types, coercion, ad hoc
polymorphism, universal types, existential types, unfolding,
intersection types
Abstract inheritance
• declarative relation among entities
Inheritance networks
isa-trees -- partial ordering
isa/is-not -- bipolar, is-not inference
Non-monotonic reasoning
Nixon is-a Quaker
Nixon is-a Republican
Quakers are Pacifists
Republicans are not Pacifists
Incremental system
evolution is in practice
non-monotonic!
Taxonomies and predicate logic
The subtype relation
Subsections:
Types as sets
The subtype refinement relation
Objects as records
Types as sets
The subtype refinement relation
The function subtype relation
Objects as records
The object subtype relation
Subtyping -- examples
type any = { }
type entity = { age : int }
type vehicle = { age : int, speed : int }
type machine = { age : int, fuel : string }
type car = { age : int, speed : int, fuel : string }
Subtyping rules
Subtyping in Emerald
S conforms to T
• S provides at least the operations of T
• for each operation in T, the corresponding
operation in S has the same number of
arguments
• the type of the result of operations of S
conform to those of the operations of T
• the types of arguments of operations of T
conform to those of the operations of S
Flavors of polymorphism
Typing -- protection against errors
static -- type checking at compile time
strong -- all expressions are type consistent
Untyped -- flexibility
bitstrings, sets, -calculus
Exceptions to monomorphic typing:
overloading, coercion, subranging, value-sharing (nil)
The nature of types
Flavors of polymorphism
• inclusion polymorphism -- to model
subtypes and inheritance
• parametric polymorphism -- uniformly on a
range of types
• intersection types -- coherent overloading
Inheritance -- incremental
modification
• Result = Parent + Modifier
Independent attributes: M disjoint from P
Overlapping attributes: M overrules P
Dynamic binding
Type abstraction
Subsections:
A simple type calculus
Intersection types
Bounded polymorphism
The lambda calculus -- terms
The lambda calculus -- laws
The lambda calculus -- substitution
Beta conversion -- examples
The lambda calculus -- properties
A simple type calculus
The subtype calculus
Subtypes -- examples
int S(int x) { return x+1; }
int twice(int f(int), int y) { return f(f(y)); }
int twice_S(int y) { return twice(S,y); }
Types in C++
int SD(double x) { return x+1; }
SD example
class P {
public:
P() { _self = 0; }
virtual P* self() {
return _self?_self->self():this;
}
virtual void attach(C* p) {
_self = p;
}
private:
P* _self;
};
P
class C : public P {
public:
C() : P(this) { }
C* self() {
return _self?_self->self():this;
}
void attach(P* p) {
p->attach(self());
}
void redirect(C* c) { _self = c; }
private:
C* _self;
};
C <= P
ANSI/ISO
rejected
Subtyping in C++
Intersection types
The intersection type calculus
Intersection types -- examples
Overloaded function selection rules
• [1] no or unavoidable conversions -- array->
pointer, T -> const T
• [2] integral promotion -- char->int, short->
int, float->double
• [3] standard conversions -• int->double, double->int, derived* -> base*
• [4] user-defined conversions -- constructors
and operators
• [5] ellipsis in function declaration -- ...
Multiple arguments -- intersect rule
better match for at least one
argument and at least as good a
match for every other argument
Overloading in C++
void f(int, double);
void f(double, int);
f(1,2.0);
f(int, double);
f(2.0,1);
f(double,int);
f(1,1);
error: ambiguous
example
class P;
class C;
void f(P* p) { cout << "f(P*)"; }
(1)
void f(C* c) { cout << "f(C*)"; }
(2)
class P {
public:
virtual void f() { cout << "P::f"; }
};
class C : public P {
public:
virtual void f() { cout << "C::f"; }
};
(3)
(4)
Static versus dynamic selection
P* p = new P
static and dynamic P*
C* c = new C;
static and dynamic C*
P* pc = new C;
static P*, dynamic C*
f(p);
f(c);
f(pc);
f(P*)
f(C*)
f(P*)
p->f();
c->f();
pc->f();
P::f
C::f
C::f
Bounded polymorphism
The bounded type calculus
Parametrized types -- examples
Bounded quantification -- examples
Point* move(Point* p, int d);
require int Point::x
Point* move(Point* p, int d) { p.x += d; return p; }
example move
template< class T >
requires T::value()
class P {
public:
P(T& r) : t(r) {}
int operator==( P<T>& p) {
return t.value() == p.t.value();
}
private:
T& t;
};
Type abstraction in C++
template< class T >
class A {
public:
virtual T value() = 0;
};
class Int : public A<int> {
public:
Int(int n = 0) : _n(n) {}
int value() { return _n; }
private:
int _n;
};
A<T>
Int <= A<int>
Type instantiation
Int i1, i2;
P<Int> p1(i1), p2(i2);
if ( p1 == p2 ) cout << "OK" << endl;
OK
Example P
Existential types -- hiding
The existential type calculus
Existential types -- examples
Packages -- examples
class event {
protected:
event(event* x) : ev(x) {}
public:
int type() { return ev->type(); }
void* rawevent() { return ev; }
private:
event* ev;
};
event
class xevent : public event {
public:
int type() { return X->type(); }
private:
struct XEvent* X;
};
X
Hiding in C++
Self-reference
A calculus for recursive types
Recursive types -- examples
Inheritance semantics -- self-reference
Object inheritance -- dynamic binding
Object inheritance -- contravariance
Bounded type constraints
Inheritance and constraints
Inheritance != subtyping
Eiffel
class C inherit P redefine eq
feature
b : Boolean is true;
eq( other : like Current ) : Boolean is
begin
Result := (other.i = Current.i) and
(other.b = Current.b)
end
end C
Inheritance and subtyping in Eiffel
p,v:P, c:C
v:=c;
v.eq(p);
error p has no b
Example
Summary
1
Abstract inheritance
• abstract inheritance -- declarative relation
• inheritance networks -- non-monotonic
reasoning
• taxonomic structure -- predicate calculus
2
The subtype relation
•
•
•
•
types -- sets of values
the subtype relation -- refinement rules
functions -- contravariance
objects -- as records
3
Flavors of polymorphism
• typing -- protection against errors
• flavors -- parametric, inclusion,
overloading, coercion
• inheritance -- incremental modification
mechanism
4
Type abstraction
• subtypes -- typed lambda calculus
• overloading -- intersection types
• bounded polymorphism -- generics and
inheritance
5
Existential types
• hiding -- existential types
• packages -- abstract data types
6
Self reference
• self-reference -- recursive types
• object semantics -- unrolling inheritance -dynamic binding
• subtyping -- inconsistencies
Questions
1. How would you characterize inheritance as applied in knowledge
representation? Discuss the problems that arise due to non-monotony.
2. How would you render the meaning of an inheritance lattice? Give
some examples.
3. What is the meaning of a type? How would you characterize the
relation between a type and its subtypes?
4. Characterize the subtyping rules for ranges, functions, records and
variant records. Give some examples.
5. What is the intuition underlying the function subtyping rule?
6. What is understood by the notion of objects as records? Explain the
subtyping rule for objects.
7. Discuss the relative merits of typed formalisms and untyped
formalisms.
8. What flavors of polymorphism can you think of? Explain how the
various flavors are related to programming language constructs.
9. Discuss how inheritance may be understood as an incremental
modification mechanism.
10. Characterize the simple type calculus
, that is the syntax, type
assignment and refinement rules. Do the same for
and
.
11. Type the following expressions: (a)
, (b)
and (c)
12. Verify whether: (a)
,
(b)
(c)
13. Explain how you may model abstract data types as existential
types.
14. What realizations of the type
can you
think of? Give at least two examples.
15.Prove that
.
16.Prove that
, for
.
Further reading
As further reading I recommend [CW85] and [Pierce93]. As
another source of material and exercises consult [Palsberg94]. An
exhaustive overview of the semantics of object systems, in both
first order and second order calculi, is further given in
[ObjectCalculus].