Prev | Next |
Introduction to abstract data types |
---|
Abstraction is a suppression of detail. You can think of a function as abstracting a task or algorithm. The interface provides only the abstract view, telling what the function accomplishes. The implementation provides the concrete view, showing the details. Functions abstract computation. But what about the data on which computation is performed? If you have only functions as an abstraction tool, then your data is always concrete. There are good reasons for wanting to abstract away details of the data as well as to abstract details of computation.
You cannot hide the details of the representation from all functions. Some, of course, must deal with the data at a very concrete, detailed level. So how can the details be hidden? The answer is that those functions that need to see the details are part of the abstract data type. An abstract data type is a type together with some functions that work on that type. The representation of the type is visible only to the functions that are part of the abstract data type. When you change the implementation of an abstract data type, you only need to change those functions that are part of the abstract data type. |
Kinds of ADT |
---|
There are two major kinds of ADT: destructive and nondestructive. Nondestructive ADTs are also called persistent ADTs. Destructive ADTs are characterized by functions that change the data that is stored. The functions in a destructive ADT are typically procedures or mixed functions, although some of the functions are usually pure. The functions in a nondestructive ADT must all be pure. They cannot change anything. |
Interfaces | ||||
---|---|---|---|---|
An interface to an ADT tells a user of the ADT everything that he or she needs to know, and no more. The interface consists of two parts: the signature and the semantics. Signature. The signature consists of the name of the type and prototypes for the functions that are part of the ADT. For example, here is the signature for an ADT that is a stack of integers. (Is this a destructive or nondestructive ADT?)
Semantics. The semantics of an ADT gives meanings to the functions. It consists of a description of the data that is represented, and contracts for the functions. Here is the semantics of our integer stack ADT.
|
Implementation |
---|
The implementation of an ADT provides a representation of the type and implementations of the functions. It is written in the programming language that you are using, such as C/C++. One way to create an abstract data type is to put the type in the header file, along with prototypes for the functions. Doing things this way has a serious defect: it makes the representation of the type available to all functions, and so does not hide it, since that representation is in the header file. Ways to improve this are discussed later, under classes. |
Destructive ADT example | ||||||
---|---|---|---|---|---|---|
Here is a full implementation of the IntStack ADT outlined above. In the header file, we put the signature and the type. In the implementation file, we put the implementation, along with documentation of the implementation. This implementation assumes that a function called abort is available to exit the computation at an error.
To use the IntStack ADT, you would include its header file, and use the type and functions.
Suppose that function main had attempted to use st.top directly. Doing so would have been a logical error, since data value st.top is part of the representation of stacks, and should not be visible outside the ADT implementation. Unfortunately, the compiler will allow us to make that error. Using classes, covered later, it is possible to make such an error impossible to make. |
Nondestructive ADT example | ||||||
---|---|---|---|---|---|---|
Here is another example of an abstract data type. This is a nondestructive stack ADT. Although it provides stacks, it is quite different from the previous ADT. This ADT does not attempt to recover memory, since doing so for this kind of data type is beyond the scope of these notes.
To use this ADT, you would include its header file, and use its type and functions. You must be sure to use them according to the signature.
|
Prev | Next |