Chapter 1

Chapter 11: Abstract Data Types and
Encapsulation Concepts
•
•
•
•
•
•
•
The Concept of Abstraction
Introduction to Data Abstraction
Design Issues for Abstract Data Types
Language Examples
Parameterized Abstract Data Types
Encapsulation Constructs
Naming Encapsulations
11-1
The Concept of Abstraction
• An abstraction is a view or representation
of an entity that includes only the most
significant attributes
• The concept of abstraction is fundamental
in programming (and computer science)
• Nearly all programming languages support
process abstraction with subprograms
• Nearly all programming languages
designed since 1980 support data
abstraction
11-2
Introduction to Data Abstraction
• An abstract data type is a user-defined
data type that satisfies the following two
conditions:
– The representation of, and operations on,
objects of the type are defined in a single
syntactic unit
– The representation of objects of the type is
hidden from the program units that use these
objects, so the only operations possible are
those provided in the type's definition
11-3
Advantages of Data Abstraction
• Advantage of the first condition
– Program organization, modifiability
(everything associated with a data structure is
together), and separate compilation
• Advantage of the second condition
– Reliability:
by hiding the data representations, user code
cannot directly access objects of the type or
depend on the representation, allowing the
representation to be changed without
affecting user code
11-4
Example of Implementation hiding
• A bounded buffer with indexes front & rear:
• The public view is different from the private view
(implementation)
11-5
Design Issues
• A syntactic unit to define an ADT
• Built-in operations
– Assignment
– Comparison
• Common operations
– Accessors
– Constructors
– Destructors
• Parameterized ADTs
11-6
Language Examples: Ada
• The encapsulation construct is called
packages
– Specification package (the interface)
– Body package (implementation of the entities
named in the specification)
• Two ways for Information Hiding
– The representation of type appears in a part of the
specification called the private part
• More restricted form with limited private types:
objects of this type have no built-in operations
– Define the ADT as a pointer and provide the pointedto structure’s definition in the body package, whose
entire contents are hidden from clients.
11-7
An Example in Ada
package Stack_Pack is
-- public interface
type stack_type is limited private;
max_size: constant := 100;
function empty(stk: in stack_type) return Boolean;
procedure push(stk: in out stack_type; elem:in Integer);
procedure pop(stk: in out stack_type);
function top(stk: in stack_type) return Integer;
private -- hidden from clients
type list_type is array (1..max_size) of Integer;
type stack_type is record
list: list_type;
topsub: Integer range 0..max_size) := 0;
end record;
end Stack_Pack
11-8
Language Examples: C++
• Based on C struct type and Simula 67
classes
• The class is the encapsulation device
• All of the class instances of a class share a
single copy of the member functions
• Each instance of a class has its own copy of
the class data members
• Instances can be static, stack dynamic, or
heap dynamic
11-9
Language Examples: C++ (continued)
• Information Hiding
– Private clause for hidden entities
– Public clause for interface entities
– Protected clause for inheritance (see Ch 12)
11-10
An Example in C++
class stack {
private:
int *stackPtr, maxLen, topPtr;
public:
stack() { // a constructor
stackPtr = new int [100];
maxLen = 99;
topPtr = -1;
};
~stack () {delete [] stackPtr;};
void push (int num) {…};
void pop () {…};
int top () {…};
int empty () {…};
}
void main() {.......
stack stk; //Create an instance of the stack class
..........
}
11-11
Language Examples: C++ (continued)
• Constructors:
– Name is the same as the class name
– Implicitly called when an instance is created
– initialize the data members of instances (they do not create
the objects)
– May also allocate storage if part of the object is heapdynamic
– Can include parameters to provide parameterization of the
objects
– Example:
struct Complex { float re; float im;
Complex(float r, i) {re = r; im= i;}
};
Complex x (1, 2);
//need to give parameters for the
//constructer
11-12
Language Examples: C++ (continued)
• Destructors
– Name is the class name, preceded by a tilde (~)
– Implicitly called when the object’s lifetime ends
– cleanup after an instance is destroyed; usually
just to reclaim heap storage
11-13
Language Examples: C++ (continued)
• A friend declaration within a class gives
nonmember function access to the private
members of the class.
– Necessary in C++
• See the next two pages for an example.
– The class List defines a circularly linked list
• push: add to the front
• put: add at the back
– The class Cell is used to form lists.
11-14
Example of a circularly linked list
• The definition of the class Cell:
class Cell {
int info;
Cell * next;
Cell (int i) {info = i; next =
this;}
Cell(int i, Cell * n) {info =
i; next = n; }
friend class List;
};
11-15
Example of a circularly linked list
(cont)
• The definition of the class List:
class List {
cell *rear;
public:
void put(int x) {rear->info = x;
rear = rear->next =
new Cell(0, rear->next);};
void push(int x) {rear->next =
new Cell(x, rear->next);
int pop ( );
int empty ( ) {return rear == rear-> next;}
List( ) {rear = new Cell(0);}
~List( ) { while (!empty( )) pop( );}
};
int List::pop( ){
if (empty( )) return 0;
Cell *front = rear->next; rear->next = front->next;
int x = front->info; delete front; return x;}
11-16
Language Examples: Java
• Similar to C++, except:
– All user-defined types are classes
– All objects are allocated from the heap and
accessed through reference variables (see the
next page)
– Individual entities in classes have access control
modifiers (private or public), rather than clauses
– Java has a second scoping mechanism, package
scope, which can be used in place of friends
• All entities in all classes in a package that do not
have access control modifiers are visible throughout
the package (also see page 28)
11-17
An Example in Java
class StackClass {
private:
private int [] stackRef;
private int maxLen, topIndex;
public StackClass() { // a constructor
stackRef = new int [100];
maxLen = 99;
topPtr = -1;
};
public void push (int num) {…};
public void pop () {…};
public int top () {…};
public boolean empty () {…};
}
...........
StackClass myStack = new StackClass();
11-18
Parameterized Abstract Data Types
• Parameterized ADTs allow designing an
ADT that can store any type elements
• Also known as generic classes
• C++ and Ada provide support for
parameterized ADTs
11-19
Parameterized ADTs in C++
• Classes can be somewhat generic by writing
parameterized constructor functions
• The following makes the stack generic in size
– Change the constructor function in page 12 as follows:
stack (int size) {
stkPtr = new int [size];
maxLen = size - 1;
top = -1;
};
…
stack stk(100);
11-20
Parameterized ADTs in C++
(cont)
• The following makes the type of the stack generic
– element of the stack has the type Type:
template <class Type> class stack{
int topPtr;
int maxLen;
Type * stkPtr;
public:
Stack(){stkPtr = new Type[100]; maxLen = 99;
topPtr = -1;}
Stack(int size){stkPtr = new Type[size];
maxLen = size-1; topPtr = -1;}
~Stack( ) {delete stkPtr;}
void push(Type a) {stkPtr[++topPtr] = a;}
Type pop( ) {topPtr--; return stkPtr[topPtr+1];}
};
11-21
Parameterized ADTs in C++
(cont)
• When the class is used as a type name, it must be supplied a
type as an explicit parameter, e.g.,
stack <int> s (99);
stack <char> t (80);
• If the body of a member function appears outside a class
declaration, then a type parameter has to be introduced
afresh, e.g.,
template <class x> void stack <x>::push(x a){
topPtr++;
stkPtr[topPtr] = a;
}
Another name x can be used instead of T
11-22
Overloaded Subprograms
• An overloaded subprogram is one that has
the same name as another subprogram in
the same referencing environment
– Every version of an overloaded subprogram has
a unique protocol
• C++, Java, C#, and Ada
– include predefined overloaded subprograms
– allow users to write multiple versions of
subprograms with the same name
– usually used to define overloading constructors
11-23
Encapsulation constructs for large
programs
• Large programs have two special needs:
– Some means of organization, other than simply
division into subprograms
– Some means of partial compilation (compilation
units that are smaller than the whole program)
• Obvious solution: a grouping of
subprograms that are logically related into
a unit that can be separately compiled
(compilation units)
• Such collections are called encapsulation
11-24
Encapsulation in C
• Files containing one or more subprograms
can be independently compiled
• The interface to such file (library) is placed
in a header file
• The header file is used in the client code,
using the #include preprocessor
specification, so that references to
functions and data in the client code can be
type-checked.
11-25
Ada Packages
• Ada specification packages can include
any number of data and subprogram
declarations
• Ada packages can be compiled separately
• A package’s specification and body parts
can be compiled separately
11-26
Naming Encapsulations
• Large programs may consist of many
independently written codes, where naming
conflicts might occur.
• A naming encapsulation define name scopes that
assist in avoiding name conflicts.
• C++ Namespaces
– Can place each library in its own namespace and qualify
names used outside with the namespace
– Example of declaration:
namespace MyStack{…}
– Example of references:
using MyStack::topPtr;
using namespace MyStack;
11-27
Naming Encapsulations
(cont)
• Java Packages
– Packages can contain more than one class
definition;
– Clients of a package can use fully qualified
name or use the import declaration
– Example of declaration:
package myStack;
– Example of references:
import myStack.*
import myStack.topPtr;
11-28