Outline
Other Material
We will examine various abstraction mechanisms
We will present a short history of the development of abstraction tools.
Abstraction is the purposeful suppression, or hiding, of some details of a process or artifact, in order to bring out more clearly other aspects, details, or structure.
Information hiding is the purposeful omission of details in the development of an abstract representation.
Information hiding is what allows abstraction to control complexity.
Think of an atlas, and the various different levels of maps
Each level contains information appropriate to the level of abstraction.
At the highest level of abstraction we view a program as a community of interacting objects.
Important characteristics here are the lines of communication between the various agents.
The next level of abstraction is found in some (but not all) OO languages. A package, Unit or Name Space allows a programmer to surround a collection of objects (a small community in itself) with a layer, and control visibility from outside the module.
The next level of abstraction considers the relationship between two invidual objects. Typically one is providing a service, and the other is using the service.
We can next examine just the person providing a service, independent of the client. We define the nature of the services that are offered, but not how those services are realized.
Interfaces are one way to describe servies at this level of abstraction.
interface Stack { public void push (Object val); public Object top () throws EmptyStackException; public void pop () throws EmptyStackException; }
Next we look at the services provided, but from the implementation side:
public class LinkedList implements Stack ... { public void pop () throws EmptyStackException { ... } ... }
Concern here is with the high level approach to providing the designated service.
Finally, we consider the implementation of each method in isolation.
public class LinkedList implements Stack ... { ... public void pop () throws EmptyStackException { if (isEmpty()) throw new EmptyStackException(); removeFirst(); // delete first element of list } ... }
Every level is important, and often you move quickly back and forth between levels.
A critical problem in early stages of development is to determine what details are appropriate at each level of abstraction, and (often more importantly) what details should be omitted.
One does not want to ignore or throw away important information
But one does not want to manage too much information, or have the amount of information hide critical details.
Two of the most important types of abstraction are the following:
Division into parts takes a complex system, and divides into into component parts, which can then be considered in isolation.
Characterized by sentences that have the words ``has-a''
Allows us to drop down a level of complexity when we consider the component in isolation.
Is-a abstraction takes a complex system, and views it as an instance of a more general abstraction.
Characterized by sentences that have the words ``is=a''
Allows us to categorize artifacts and information and make it applicable to many different situations.
An important aspect of division into parts is to clearly characterize the connection, or interface, between to components.
Allows for considering multiple different implementations of the same interface.
For example, a car can have several different types of engine and one transmission.
Another way to think of an interface is as a way of describing the service that an object provides.
The interface is a contract for the service--if the interface is upheld, then the service will be provided as described.
While is-a and has-a are two important types of abstraction, there are others.
Composition is one example; a form of has-a; characterized by the following
Examples include regular expressions, type systems, windows, lots of other complex systems.
Patterns are another attempt to document and reuse abstractions.
Patterns are description of proven and useful relationships between objects; which can help guide the solution of new problems.
Example pattern, Proxy:
Will have many more patterns in a later chapter.
Another way to better understand OOP is to put it in context with the history of abstraction in computer science.
Assembly languages and linkers were perhaps the first tools used to abstract features of the bare machine.
Libraries of procedures and functions (such as mathematical or input/output libraries) provided the first hints of information hiding.
They permit the programmer to think about operations in high level terms, concentrating on what is being done, not how it is being performed.
But they are not an entirely effective mechanism of information hiding.
int datastack[100]; int datatop = 0; void init() // initialize the stack { datatop = 0; } void push(int val) // push a value on to the stack { if (datatop < 100) datastack [datatop++] = val; } int top() // get the top of the stack { if (datatop > 0) return datastack [datatop - 1]; return 0; } int pop() // pop element from the stack { if (datatop > 0) return datastack [--datatop]; return 0; }
Where can you hide the implementation?
Modules basically provide collections of procedures and data with import and export statements
Solves the problem of encapsulation -- but what if your programming task requires two or more stacks?
David Parnas described two principles for the proper use of modules:
An Abstract Data Type is a programmer-defined data type that can be manipulated in a manner similar to system-provided data types
But ADTs were important not because they were data structures, but because they provided an easily characterized service to the rest of an application.
Looking at this history, we can separate it into three periods of time
Characterists of Objects
What will be the next evolutionary step in software?
Prediction is hard, particularly about the future.
However, one you have accepted the idea of an application formed from interacting agents, there is no reason why those components must exist on the same computer (distributed computing) or be written in the same language (components).
So some of the trends we see today in software are natural results of the OOP mind set.