Let us do an example. Imagine you are writing software for banks and bookkeepers and want to start developing a "data type library". One very basic data type is an account. What do we expect an account to do?
Account, owner (person/company), Deposit (money or papers), Character, Bool, ... .
Types = (Account,Owner,Deposit (currency), Character, Bool, ...) Operations Create: Owner x Deposit -> Account, Remove: Account -> Deposit, Add : Account x Deposit -> Account, Subtract: Account x Deposit -> Account, Log : Account -> Character, + : Account x Account -> Deposit, = : Account x Account -> Bool, .... Equations (Axioms) Subtract (Add (account1,b),b)=account1
The view of the user of an account is described above. This description therefore contains:
Another easy example is the stack:
Types = (entry,stack,bool) or (stack(entry),bool) Operations PUSH: entry x stack -> stack, POP: stack -> entry x stack, EMPTY: stack-> bool, l: -> stack ( equivalent to NEW: -> stack ?) l is an empty stack FULL : stack -> bool ? Examples (Axioms) POP(PUSH(e,s)) = e,s EMPTY(l) = true EMPTY(PUSH( , ))= false POP(l) = l (or error object)
Definition used by B. Meyer:
POP: stack -> stack TOP: stack -> entry POP(PUSH(e,s)) = s TOP(PUSH(e,s)) = e
The target is to get simple interfaces and general useable data types. The principles we used here already are:
Is it possible to implement abstract data types in classical languages? A lot can be done provided programmers are very disciplined. But this is of no more use if software has a long lifecycle. The programmers change often and a lot of code changes are required. But there are limits:
An abstract data type is the external description of an object. The specification of the data type defines the external interface and its behavior to be provided by the object. As mentioned in the chapter about abstract data types an object normally has additional axioms added to the specification. These additional axioms are necessary to provide the implementation selected. The object can be viewed as the real implementation of an abstract data type which is ready in storage to receive messages of the defined signature.
An object has two sides:
Every object has methods to be executed when receiving a message.
METHOD = PROGRAM executing an OPERATION of an abstract data type MESSAGE = CALL of a METHOD.
5 square
MyDouble f=5,r; r= f.square;
There are three ways to look on an object:

In C++ a class consists of its declaration part (H-file) and its definition part (C-file). Unfortunately these two parts can be merged into one: i.e. all may be included to the H-file (and sometimes must be - for example inline methods). A good idea would have been to put into the header file only the external consumer side description of a class. In C++ even some internal or implementation parts of the description (protected members, internal methods) have to be included in the H-file.
The implementer's side of a class consists of the coded methods and the specification of internal variables. Here it is told how things are to be done. But this side is invisible from the consumer side. This is called information hiding. The consumer knows the behavior of a class - the interface. But he/she does not know how the class obtains the results returned by its methods and how the data is internally represented.
A class can be viewed in the following ways:
Classes can be ordered hierarchically. This is explained in the section about inheritance . A class contains:
Realization of the class Account in a classical language:
DCL 1 KONTO BASED(*), 2 KONTOID CHAR(8), 2 BETRAG BIN FIXED(31), 2 INHABER CHAR(240), 2 ...; EINZAHLE: PROCEDURE(KPOINTER,EBETRAG,KID); ... END;
Usage:
DCL KONTO1 CHAR(LENGTH(KONTO)); ... CALL EINZAHLE (ADDR(KONTO1),200,'K147I');
Realisation of class Account in Smalltalk:
Object subclass: #Konto instanceVariableNames:'kontoid betrag inhaber ...' classVariableNames:'Bankleitzahllist' einzahle: einBetrag " der uebergebene Betrag wird auf den Empfaenger eingezahlt " betrag := betrag + einBetrag.
Class Account in C++
class Konto {
protected:
Int Kontoid;
Waehrung Stand;
Person* Inhaber;
public:
static Array Bankleitzahllist;
public:
int Einzahle (const Waehrung & Betrag){
Stand+=Betrag;
}
int Eroeffne (Person* cc, const Waehrung & Betrag){
if (! cc-check()) return FALSE;
Stand = Betrag;
Inhaber= cc;
return TRUE;
}
} // end class Konto
There exist two types of methods:
Usage of Smalltalk class Account:
k1 := Konto new . k1 einzahle: (DM new:200 ). "DM subclass of Waehrung"
The method new allocates storage to the instance variables of k1. These instance variables still point to undefined objects. Therefore the method 'einzahle' will fail.
In most languages the constructor of an object will only allocate the storage needed for the object. The state data will normally be in an undefined state after creation. To initialize an object with valid default data an initialization method has to be included.
init: einBetrag betrag := einBetrag.
class method eroeffne
eroeffne: einBetrag ^(self new) init: einBetrag
Usage in C++
Konto K1 ; /* similiar to K1:= Konto new */ Person Person1; DM Betrag(200) ; // DM subclass of Waehrung .... K1.Eroeffne(&Person1,Betrag); //initialize state of K1 DM Betrag2(150); K1.einzahle(Betrag2);
The declaration of K1 operates as new in Smalltalk. The state of the object K1 is undefined if no initialization is defined in the constructor method for class 'Konto'.
There exist to construction elements to build a new class from others. These are Aggregation and Inheritance. Inheritance will be described in the next chapter.
Aggregation means that an object A is part of another object B. B uses the object A. It can be used to describe the internal state of A, for identification of A (f.e. the database key of a business object) or other purposes. Aggregation is also called Client-Server relationship. The Client B is the user of the class A (the server). The client sent messages to objects of the used classes. By this the client 'delegates' responsibilities to its servers. There exist different aggregation types:
Even when object oriented methodology is used black box reuse seemed to be not possible in every case. At least sub classing with overwriting methods is often necessary. In the end object orientation brought software engineering a big step forward but did not reach all. So the question of reusability of designs arises.
As described in (13) in architecture 'patterns' are used to describe elements solving problems occurring again and again when designing a building. Such patterns can also be collected for software elements. Besides cataloging design ideas solving frequently arising problems patterns define a language in which we can explain and communicate designs.
Target of design patterns is:
Elements of patterns are
An example of a design pattern is a Model-View-Controller (MVC). In a concrete Design the model would represent one or several business objects (f.e. figures in our graphical editor), the views would be the different presentations of figures (star character on printer page or graphical view on screen ...). A controller would be added if user interactions are defined.
For a further study of this matter have a look into (13). Own experience in OO design is recommended when studying this book.