Procedural abstraction
\oopindex{procedural abstraction}
In the specification of the abstract data type stack
given above, the behavior of the stack has been characterized by means of
equational axioms.
We distinguish two ways to construct a stack,
namely by using the constructor function new and by applying the function push.
In addition to these constructors the operations empty, top and pop
are specified.
A different way of characterizing the behavior of a stack is by a matrix relating the
meaning of the various operations to the constructors.
\begin{center}
\mbox{}\hspace{-2.5cm}
\begin{tabular}{| r | c c |} \hline
& new & push(x,s') \\ \cline{1-3}
empty(s) & true & false \\
top(s) & error & x \\
pop(s) & error & s' \\ \hline
\end{tabular}
\end{center}\ln
We have omitted the preconditions for the operations top and pop,
and instead defined the result as error.
\nop{
The different way to implement an abstract data type may be distinguished
according to how the matrix describing the abstract type is partitioned.
See [Cook90].
}
Traditional ways of implementing abstract data types
favor a horizontal partitioning of the matrix.
This results in defining the operations on a concrete representation
of the type by means of a case-statement distinguishing between
the possible constructors of the type.
In contrast, the object oriented approach to implementing the
abstract data types may be regarded as a vertical partitioning
of the matrix.
In this approach, the operations are grouped around the constructors.
This method is referred to in [Cook90] as procedural abstraction,
since the operations defined for the constructors provide
a procedural interface to the abstract type comprising these constructors.
The differences between these approaches come to light
when extending an abstract type with either a constructor or operation.
Adding a constructor to a traditional abstract data type implementation
requires to extend the definition of each operation
with an additional case defining the result of the operation for
the new constructor.
In practice this means a modification of the source code.
Using procedural abstraction, as in the object oriented approach,
allows to add a new constructor incrementally.
One merely has to add the new constructor defining the results of each
operation.
When adding a new operation to an abstract data type implementation,
it depends on the implementation language whether access to the source
code is needed to add the operation (which must define the result
for each possible constructor).
In the object oriented approach, adding a new operation requires the use
of inheritance, to create a variant that inherits the
functionality of the original constructor while adding the new operation.
\nop{
For a discussion of the tradeoffs, see [Cook90].
}