poosd-08.ppt

Download Report

Transcript poosd-08.ppt

Principles of Object-Oriented
Software Development
Abstract data types
Abstract data types
Introduction
Abstraction and types
Algebraic specification
Decomposition -- modules versus objects
Types versus classes
Summary
Q/A
Literature
Abstract data types
•
•
•
•
abstraction and types
algebraic specification
modules versus classes
types as constraints
Additional keywords and phrases:
control abstractions, data abstractions, compiler support,
description systems, behavioral specification, implementation
specification
Abstraction and types
Subsections:
Abstraction in programming languages
Foundational perspectives -- types as constraints
Objectives of typed OOP
Abstraction in
programming languages
Abstraction
programming methodology
• control abstractions -- structured programming
• data abstraction -- information hiding
The kind of abstraction provided by ADTs can be supported by any
language with a procedure call mechanism (given that appropriate
protocols are developed and observed by the programmer). [DT88]
A foundational perspective
types as constraints
Abstract Data Types -- foundational perspective
unambiguous values in some semantic domain
Mathematical models -- types as constraints
algebra -- set oriented
second order lambda calculus -- polymorphic types
constructive mathematics -- formulas as types
Mathematical models for types
Objectives of typed OOP
system description
• packaging in a coherent manner
• flexible style of associating operations with
objects
• inheritance of description components -reuse, understanding
• separation of specification and
implementation
• explicit typing to guide binding decisions
Algebraic specification
Subsections:
Signatures -- generators and observers
Equations -- specifying constraints
Initial algebra semantics
Objects as algebras
Algebraic specification -- ADT
adt bool is
functions
true : bool
false : bool
and, or : bool * bool -> bool
not : bool -> bool
axioms
[B1] and(true,x) = x
[B2] and(false,x) = false
[B3] not(true) = false
[B4] not(false) = true
[B5] or(x,y) = not(and(not(x),not(y)))
end
Bool
Signatures -- generators and observers
Algebraic specification
Generators -- basis and universe
The ADT Seq
Equations -- specifying constraints
Natural numbers
Nat
functions
0 : Nat
S : Nat -> Nat
mul : Nat * Nat -> Nat
plus : Nat * Nat -> Nat
axioms
[1] plus(x,0) = x
[2] plus(x,Sy) = S(plus(x,y))
[3] mul(x,0) = 0
[4] mul(x,Sy) = plus(mul(x,y),x)
end
mul(plus(S 0,S 0),S 0) -[2]->
mul(S(plus(S 0,0)), S 0) -[1]->
mul(SS 0,S 0) -[4]->
plus(mul(SS0,0),SS0) -[3]->
plus(0,SS0) -[2*]-> SS0
Symbolic evaluation
Sets
Set
Axioms
The ADT Set
Equivalence classes for Set
Initial algebra semantics
Interpretations and models
Interpretations of Bool and Nat
Initial models
Structure and interpretation
Objects as algebras
Abstract Data Type -- applicative
functions
new : stack;
push : element * stack -> stack;
empty : stack -> boolean;
pop : stack -> stack;
top : stack -> element;
axioms
empty( new ) = true
empty( push(x,s) ) = false
top( push(x,s) ) = x
pop( push(x,s) ) = s
preconditions
pre: pop( s : stack ) = not empty(s)
pre: top( s : stack ) = not empty(s)
end
stack
Dynamic state changes -- objects
object account is
functions
bal : account -> money
methods
credit : account * money -> account
debit : account * money -> account
error
overdraw : money -> money
axioms
bal(new(A)) = 0
bal(credit(A,M)) = bal(A) + M
bal(debit(A,M)) = bal(A) - M if bal(A) >= M
error-axioms
bal(debit(A,M)) = overdraw(M) if bal(A) < M
end
account
The interpretation of change
Example - a counter object
object ctr is
ctr
function n : ctr -> nat
method incr : ctr -> ctr
axioms
n(new(C)) = 0
n(incr(C)) = n(C) + 1
end
The object ctr
Abstract evaluation
<n(incr(incr(new(C)))),{ C }> -[new]->
<n(incr(incr(C))),{ C[n:=0] }> -[incr]->
<n(incr(C)),{ C[n:=1] }> -[incr]->
<n(C), { C[n:=2] }> -[n]->
<2, { C[n:=2] }>
An example of abstract evaluation
Decomposition -- modules versus
objects
Subsections:
Abstract interfaces
Representation and implementation
Adding new generators
Adding new observers
Decomposition -- matrix
data abstraction
Modules -- operation oriented
ADT
organized around observers -- representation hiding
Objects -- data oriented
OOP
organized around generators -- method interface
Abstract interfaces
Modules -- a functional interface
ADT
typedef int element;
struct list;
extern list* nil();
extern list* cons(element e, list* l);
extern element head(list* l);
extern list* tail(list* l);
extern bool equal(list* l, list* m);
Modules -- a functional interface
Objects -- a method interface
OOP
template< class E >
class list {
public:
list() { }
virtual ~list() { }
virtual bool empty() = 0;
virtual E head() = 0;
virtual list<E>* tail() = 0;
virtual bool operator==(list<E>* m) = 0;
};
Objects -- a method interface
Representation and
implementation
Modules -- representation hiding
ADT
typedef int element;
enum { NIL, CONS };
struct list {
int tag;
element e;
list* next;
};
Generators
list* nil() {
nil
list* l = new list; l->tag = NIL; return l;
}
list* cons( element e, list* l) {
cons
list* x = new list;
x->tag = CONS; x->e = e; x->next = l;
return x;
}
Data abstraction and modules
Modules -- observers
ADT
int empty(list* lst) { return !lst || lst->tag == NIL; }
element head(list* l) {
require( ! empty(l) );
return l->e;
}
list* tail(list* l) {
require( ! empty(l) );
return l->next;
}
bool equal(list* l, list* m) {
switch( l->tag) {
case NIL: return empty(m);
case CONS: return !empty(m) &&
head(l) == head(m) &&
tail(l) == tail(m);
}
}
head
tail
equal
Method interface -- list
OOP
template< class E >
class nil : public list< E > {
public:
nil() {}
bool empty() { return 1; }
E head() { require( false ); return E(); }
list< E >* tail() { require( 0 ); return 0; }
bool operator==(list<E>* m) { return m->empty(); }
};
nil
template< class E >
class cons : public list< E > {
cons
public:
cons(E e, list<E>* l) : _e(e), next(l) {}
~cons() { delete next; }
bool empty() { return 0; }
E head() { return _e; }
list<E>* tail() { return next; }
bool operator==(list<E>* m);
protected:
E _e;
list<E>* next;
};
Data abstraction and objects
Adding new generators
Adding new generators -representation
ADT
typedef int element;
enum { NIL, CONS, INTERVAL };
struct list {
int tag;
element e;
union { element z; list* next; };
};
Generator
list* interval( element x, element y ) {
list* l = new list;
if ( x <= y ) {
l->tag = INTERVAL;
l->e = x; l->z = y;
}
else l->tag = NIL;
return l;
}
Modules and generators
Modifying the observers
ADT
element head(list* l) {
require( ! empty(l) );
return l->e;
}
head
for both CONS and INTERVAL
list* tail(list* l) {
require( ! empty(l) );
switch( l->tag ) {
case CONS: return l->next;
case INTERVAL:
return interval((l->e)+1,l->z);
}
}
tail
Adding new generators
OOP
class interval : public list<int> {
public:
interval(int x, int y) : _x(x), _y(y) { require( x <= y ); }
bool empty() { return 0; }
int head() { return _x; }
list< int >* tail() {
return (_x+1 <= _y)?
new interval(_x+1,_y):
new nil<int>;
}
bool operator==(list@lt;int>* m) {
return !m->empty() &&
_x == m->head() && tail() == m->tail();
}
protected:
int _x; int _y;
};
interval
Adding new observers
Adding new observers
ADT
int length( list* l ) {
length
switch( l->tag ) {
case NIL: return 0;
case CONS: return 1 + length(l->next);
case INTERVAL: return l->z - l->e + 1;
};
}
Modules and observers
Adding new observers
OOP
template< class E >
int length(list< E >* l) {
length
return l->empty() ? 0 : 1 + length( l->tail() );
}
template< class E >
class listWL : public list<E> {
listWL
public:
int length() { return ::length( this ); }
};
Objects and observers
Types versus classes
Types versus classes
• types -- type checking predicates
• classes -- templates for object creation
Type specification
syntactically -- signature
semantically -- behavior
pragmatically -- implementation
(under)
(right)
(over)
Modifications
types -(predicate constraints)-> subtypes
classes -(template modification)-> subclasses
Varieties of (compatible) modifications
behaviorally -- algebraic, axiomatic
signature -- type checking
name -- method search algorithm
(signature)
(classes)
Signature compatible modifications
behavior is approximated by signature
Semantics preserving extensions
horizontal -- Person = Citizen + { age : 0..120 }
vertical -- Retiree = Person + { age : 65..120 }
Principle of substitutability
an instance of a subtype can always be used in any context
in which an instance of a supertype can be used
Read-only substitutability
subset subtypes, isomorphically embedded subtypes
Name compatible modifications
• operational semantics -- no extra
compile/run-time checks
procedure search(name, module)
if name = action then do action
elsif inherited = nil
then undefined
else search(name, inherited)
The inheritance search algorithm
Summary
1
Abstraction and types
• abstraction -- control and data
• abstract data types -- values in a semantic
domain
• types as constraints -- mathematical models
2
Algebraic specification
•
•
•
•
signature -- producers and observers
generator universe -- equivalence classes
initial model -- no junk, no confusion
objects -- multiple world semantics
3
Decomposition -- modules
versus objects
• data abstraction -- generators/observers
matrix
• modules -- operation oriented
• objects -- data oriented
4
Types versus classes
• types -- syntactically, semantically,
pragmatically
• compatible modifications -- type, signature,
class
Questions
1. Characterize the differences between control abstractions and data
abstractions. Explain how these two kinds of abstractions may be
embodied in programming language constructs.
2. How can you model the meaning of abstract data types in a
mathematical way? Do you know any alternative ways?
3. Explain how types may affect object-oriented programming.
4. Explain how you may characterize an abstract data type by means of a
matrix with generator columns and observer rows. What benefits does
such an organization have?
5. How would you characterize the differences between the realization of
abstract data types by modules and by objects? Discuss the trade-offs
involved.
6. How would you characterize the distinction between types and
classes? Mention three ways of specifying types. How are these kinds
related to each other?
7. How would you characterize behavior compatible modifications?
What alternatives can you think of?
Further reading
There is a vast amount of literature on the algebraic specification
of abstract data types. You may consult, for example, [Dahl92].