data abstraction and encapsulation
DESCRIPTION
Data Abstraction and Encapsulation. Key research: Dennis & Van Horn CACM , March '66 first notion of abstract types and capabilities Parnas: "On the Criteria to be Used in Decomposing Systems into Modules." CACM , Dec '72 Liskov: CLU - PowerPoint PPT PresentationTRANSCRIPT
Data Abstraction and Encapsulation• Key research:
– Dennis & Van Horn CACM, March '66• first notion of abstract types and capabilities
– Parnas: "On the Criteria to be Used in Decomposing Systems into Modules." CACM, Dec '72
– Liskov: CLU– Wulf/Shaw: Alphard– Lampson: Euclid– Good: GYPSY– Xerox: Mesa– Hoare/Brinch Hansen: monitors– Wirth: Modula & Modula-2– Honeywell-Bull: Ada
Parnas's Principles
• One must provide the intended user with all the information needed to use the module and nothing more.
• One must provide the implementer with all the information needed to complete the module and nothing more.
Data Abstraction• Emphasis on behavior (operations capture behavior)
• Implementation is not important to user of abstraction
• In order to support data abstraction, language must provide:
– linguistic construct
• permits abstraction to be implemented as a unit
• supports representation specification
– ways to limit access to object
• access should only be to defined operations
• no access to representation
--> clusters, modules, forms, packages, classes...
Simple - Data Only
package earth is type continent is (Africa, Antarctica, Asia, Australia, Europe, NorthAmerica,
SouthAmerica); radius: constant float:= 6.4e6; area: constant array (continent) of float:= (30.3e9, 13.0e9, 43.3e9, 7.7e9, 10.4e9, 24.9e9, 17.8e9); population : array (continent) of integer;end earth;
Logical clustering
Information Hidingpackage trig is function sin(x: float) return Float; function cos(x: float) return Float;end trig;
package body trig is pi: constant Float:= 3.14159; function norm(x: float) return float is ...; - return x modulo 2*pi function sin(x: float) return float is ...; --return the sine of norm(x) function cosine (x: float) return float is ...; --return the cosine of norm(x)end trig
Exporting functions only
Implementation is hidden
Simple Objects
package directory_object is procedure insert(newname : in Name;
newnumber : in Number); procedure lookup(oldname : in Name;
oldnumber : out Number; found : out Boolean);
end directory_object;
package body directory_object is type Dirnode; type Dirptr is access Dirnode; type Dirnode is record entryname : Name; entrynumber : Number; left, right : Dirptr; end record;
root: dirptr;
Implements a directory
- Creates one directory- exports two procs that can operate on directory- directory itself hidden from access
(cont) Simple Objects
procedure insert(newname : in Name; newnumber : in Number) is ... -- add new newname, newnumber to the directory
procedure lookup(oldname : in Name; oldnumber : out Number; found : out Boolean); ... -- find oldname entry in directory
begin ...; -- initialize the directoryend directory_object;
- - - - - - - - - - - - - - - - - -
directory-object.insert (me, 41039);...directory_object.lookup (me, mynumber, ok);
Operations user can perform on directory
Object Classesgeneric package directory_class is procedure insert(newname: in Name; newnumber: in
Number); procedure lookup(oldname: in Name; oldnumber: out
Number; found: out Boolean);end directory_class;
package body directory_class is type Dirnode; type Dirptr is access Dirnode; type Dirnode is record entryname : Name; entrynumber : Number; left, right : Dirptr; end record; root: dirptr;
Describes an instance of a directory
(cont) Object Classes procedure insert(newname: in Name; newnumber: in Number) is ... -- add new newname, newnumber to the directory
procedure lookup(oldname: in Name; oldnumber: out Number;found: out Boolean);
... -- find oldname entry in directorybegin ... -- initialize the directoryend directory_class; - - - - - - - - - - - - - - - - - -
package homedir is new directory_classpackage workdir is new directory_class
workdir.insert (me, 41039);homedir.insert (me, 30570);workdir.lookup (me, mynumber, ok);
Derived objects
No notion of inheritance
Abstract Types - Motivation
datatype rational = rat of (int * int);
val zero = rat (0, 1);
and one = rat (1, 1);
fun op ++ (rat(m1, n1): rational,
rat(m2, n2): rational) =
rat (m1*n2 + m2*n1, n1*n2)
- - - - - - - - - - - - - - - - - - - - - - -
rat(3,2) --creates rational number 3/2
rat(6,4) --creates rational number 6/4
Abs Types - (cont) Motivation
if one ++ rat(1,2) = rat (6,4) then ... else ...
rat(0,0) -- no corresponding
rat(1,0) -- rational numbers!
- - - - - - - - - - - - - - - - - - - - - - - - Have: Rational = {rat(m,n) | m,n integer}Desire: Rational = {rat(m,n) | m,n integer; n>0;
m,n have no common factor} -- a type based on a (representation) type that does not exist -- in common languages.
abstract type: based on a set of operations: constants, functions and procedures -- values defined only indirectly.
Won’t test =although it should
Abstract Types - Example
abstype rational = rat of (int * int);with val zero = rat (0, 1); and one = rat (1, 1);
fun op // (m: int, n: int) = if n <> 0 then rat(m,n) else ... -- invalid rational number
and op ++ (rat(m1, n1): rational, rat(m2, n2): rational) =rat (m1*n2 + m2*n1, n1*n2)
Abs Types (cont) Example and op == (rat(m1, n1): rational, rat(m2, n2): rational) =
(m1*n2 = m2*n1)
and float (rat(m,n): rational) = m / n
end
- - - - - - - - - - - - - - - - - - - - - - -
val h = 1//2 --creates rational number 1/2val i = 6//4 --creates rational number 6/4
if one ++ h = = i then ... else ... -- now this works
Another Abstract Typepackage directory_type is type Directory is limited private; procedure insert(dir: in out Directory; newname: in Name;
newnumber : in Number); procedure lookup(dir: in Directory; oldname: in Name;
oldnumber: out Number; found: out Boolean);
private type Dirnode; type Directory is access Dirnode; type Dirnode is record ... end record;
end directory_type;
Implementation details in a specification!
Another Abstract Type (cont)
package body directory_type is
procedure insert(dir: in out Directory; newname: in Name;
newnumber : in Number) is
... -- add new newname, newnumber to dir
procedure lookup(dir: in Directory; oldname: in Name;
oldnumber: out Number; found: out Boolean);
... -- find oldname entry in dir
end directory_type;
Using directory_type
use directory_type; -- allows dropping dot notation
homedir: Directory;
workdir: Directory;
. . .
insert (workdir, me, 41039);
insert (homedir, me, 97548);
...
lookup (workdir, me, mynumber, ok);
Objects and Abstract Types
• Abstract types are similar to built-in types and have first-class status: values of the type are first-class. Objects, in general, are not. In object example, homedir and workdir couldn't be passed as arguments, for e.g.
• Abstract type notation is more natural: values and variables of the type are arguments rather than dot-notated prefixes.
• Abstract types work in all programming paradigms. Objects, being updatable entities, fit the imperative programming style.
Generics
generic
capacity: in positive;
type Item is private;
package queue_class is
procedure append(newitem : in Item);
procedure remove(olditem : out Item);
end queue_class;
More Genericspackage body queue_class is items : array (1..capacity) of Item; size, front, rear : Integer range 0..capacity; procedure append(newitem : in Item) is begin ... items(rear):= newitem; ...; end; procedure remove(olditem : out Item) is begin ... olditem:= items(front); ...; end end;begin front:= 1; rear:= 0;end queue_class;
Using queue_class
package line_buffer is new queue_class(120, Character);
type Transaction is record ... end record;
package audit_trail is new queue_class(100, Transaction);
T: Transaction;
. . .
line_buffer.append('*');
. . .
audit_trail.remove(T);
Generics with Dependent Types
generic
type Item is private;
type Sequence is array (Integer range <>) of Item;
with function precedes (x,y: Item) return Boolean;
package sorting is
procedure sort(seq : in out Sequence);
procedure merge(seq1, seq2 : in out Sequence;
seq : out Sequence);
end sorting;
Sorting (body)
package body sorting is
procedure sort(seq : in out Sequence) is
begin
...; if precedes(seq(i), seq(j)) then ...; ...;
end;
procedure merge(seq1, seq2 : in out Sequence;
seq : out Sequence) is
begin ...; end;
end sorting;
Using Generic
type Float_sequence is array(Integer range <>) of Float;
package ascending is new sorting(Float, Float_sequence, "<=");
package descending is new sorting(Float, Float_sequence, ">=");
. . .
type Trans_sequence is array(Integer range <>) of Transaction;
function earlier(t1, t2 : Transaction) return Boolean is
...; --return true if t1 precedes t2
end earlier;
package transaction_sorting is new sorting(Transaction,
Trans_sequence, earlier);
Arguments in Ada
Procedure/Function Genericabstraction abstraction
argument type
First class value yes yes
Reference to a variable yes yes
Procedure/function abstraction no yes
type no yes
• Oddity that Ada does not allow procedure/function arguments to procedures and functions.
• Not unusual to not allow type parameters to procedures/functions.