View
222
Download
0
Embed Size (px)
Citation preview
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
• control abstractions -- structured programming
• data abstraction -- information hiding
programming methodology
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
• 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
system description
Algebraic specification
Subsections:
Signatures -- generators and observers Equations -- specifying constraints Initial algebra semantics Objects as algebras
Algebraic specification -- ADT
Booladt 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
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 -> Nataxioms [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
stackfunctions 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
Dynamic state changes -- objects
accountobject 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
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 interfaceOOP
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 hidingADT
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) { head require( ! empty(l) ); return l->e; } list* tail(list* l) { tail require( ! empty(l) ); return l->next; } bool equal(list* l, list* m) { equal switch( l->tag) { case NIL: return empty(m); case CONS: return !empty(m) && head(l) == head(m) && tail(l) == tail(m); } }
Method interface -- listOOP
template< class E > class nil : public list< E > { nil
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(); } };
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 observersADT
element head(list* l) { head require( ! empty(l) ); return l->e; for both CONS and INTERVAL } list* tail(list* l) { tail require( ! empty(l) ); switch( l->tag ) { case CONS: return l->next; case INTERVAL: return interval((l->e)+1,l->z); } }
Adding new generators
OOP
class interval : public list<int> { interval 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; };
Adding new observers
Adding new observersADT
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 observersOOP
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 (under) semantically -- behavior (right) pragmatically -- implementation (over)
Modifications
types -(predicate constraints)-> subtypes classes -(template modification)-> subclasses
Varieties of (compatible) modifications
behaviorally -- algebraic, axiomatic signature -- type checking (signature) name -- method search algorithm (classes)
Signature compatible modifications behavior is approximated by signatureSemantics 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
Abstraction and types
• abstraction -- control and data
• abstract data types -- values in a semantic domain
• types as constraints -- mathematical models
1
Algebraic specification
• signature -- producers and observers
• generator universe -- equivalence classes
• initial model -- no junk, no confusion
• objects -- multiple world semantics
2
Decomposition -- modulesversus objects
• data abstraction -- generators/observers matrix
• modules -- operation oriented
• objects -- data oriented
3
Types versus classes
• types -- syntactically, semantically, pragmatically
• compatible modifications -- type, signature, class
4
Questions1. 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].