Object Orientation
Inroduction
This section introduces to some concepts of object oriented design and how these concepts are realized within this package. In order to be kept short, the following subsections are superficial with respect to theoretic aspects of object oriented design. Nevertheless, they should give an impression of how to bring object orientation into
Mathematica.
A single example is constructed from scratch and gradually expanded. This example is deliberately kept very simple and general in order to catch a common notion of a real world situation that needs not to be explained.
Abstract Data Type
Let us assume that the hotel manager of the "Daily Horse Inn" likes to design a very simple model of the rooms in his hotel. He likes to let rooms to persons and starts with a template for a room, called
Class in object orientation terms. Without a booking, there are no persons in the room and the corresponding field is an empty list. Once a room is occupied, it should also be possible to write bills. Here is the first version of the
Room class.
Some rooms will have a special equipment, like a television set, and a price. The basic room has no such special equipment. Because the equipment is independent of who is living in the room, it is attached to the kind of room, the class. In terms of object oriented design such a binding is called
Static. The modifier
Virtual will be explained below. The price depends on the number of persons in the room and on how the room is equipped. Because the room has no special equipment yet, it does not influence the price of this basic room. In the next cell, the
&&-operator adds definitions to an already defined class.
Once the guests checked in, there should be no change in the persons living in the room. It is therefore enough to set the
Persons field during initialization. Such a function, called a constructor, is automatically called when a
room is "created" and it has the name of the class. In the next cell, the output shows the collected class definition.
Out[4]//TableForm= |
| |  |
It is time for a first test of the class. In the next cell we create an occupied room by means of
New.
From now on, we benefit from the work we put into the class definition. A price is easily obtained. It is the same for both rooms.
| Out[7]= |  |
| Out[8]= |  |
Writing a bill is simple. The function automatically uses the correct names.
| Out[9]= |  |
| Out[10]= |  |
Inheritance
The rooms in the hotel are similar, but not identical. For the sake of comfort, the general
Room is specialized in a
Single and a
Double. We start with the
Single. Only a single person may check in. The rest is identical to the already defined
Room. In terms of object orientation, this reuse of functionality is called inheritance. In the next cell, the
Single is derived from
Room. It has an initialization routine that allows only a single person. This is passed to the initialization of
Room by means of
Super, which is a symbolic reference to the parent class constructor.
The
Double allows two persons and has a garage place that will cost extra. The modifier
Override is used to emphasize that the new member replaces the functionality in the parent class.
Because a class inherits all functionality from its parent, we can write a bill without explicitly implementing a function for a
Double room.
| Out[13]= |  |
Polymorphism
The concept of polymorphism automatically accesses functionality within the right context. For example, the
Double room defined above has a price that must take into account the extra garage. Because of the automatism, we can compare the prices for a
Single and a
Double with one or two persons without thinking about how the correct information is collected. In the next example, the extra equipment of the
Double room is automatically incorporated into the price, because the field was qualified with
Virtual.
Encapsulation
The model developed so far is not very safe with respect to privacy of hotel guests. Here is an example that shows how easy it is to get a guest's name.
| Out[18]= |  |
In order to correct this, we qualify the
Persons field with
Private. Attributes of object orientation are set on a member level, while
Mathematica's attributes are set for a method name of a class. The next command is a shortcut that avoids to rewrite the definition
Class[Room]:={..., Private.Persons={}, ...}. A default attribute
Real is automatically added, see
$DefaultInheritance.
| Out[19]= |  |
Now, it is no longer possible to read out personal data. The
Catch statement takes care of the error handling.
| Out[20]= |  |
The price can still be calculated, because it is not restricted in access.
| Out[21]= |  |
Operators and Friends
Once in a while, it is convenient to define operators on objects of a class. Here, we sum the cost of rooms. First, the operator function to be changed is unprotected.
| Out[22]= |  |
Next, we define the functionality.
We restore the protection.
| Out[24]= |  |
Now, the operator can be used.
| Out[25]= |  |
This does not affect the normal meaning of Plus.
| Out[26]= |  |
An operator or another function that accesses private members within a class can mimic the effect of "friend" in C++ with the following structure. As an example, the fire brigade that needs to know how many persons are inside the building.
| Out[28]= |  |
Without the
Block-structure, the function fails, because
Persons is a
Private field.
| Out[30]= |  |
Interface Aspects
Writing bills should be controlled. It may therefore be a good idea to prevent the redefinition of
WriteBills outside the
Room class. This is achieved by qualifying the method with
Final. In the class definition,
Final.WriteBill[]:=... sets the flag. Here, we avoid to repeat the class definition.
| Out[31]= |  |
Trying to change the bill writing function is now prevented.
| Out[32]= |  |
Because the abstract concept of a
Room does not exist in reality and only specific kinds of rooms exist, it may be a good idea to qualify the
Room class such that no non-specific room can be occupied by guests. This is done by means of the
Abstract modifier. It can be done on a class level or for selected members of the class. The next command has the same effect as defining
Abstract.Class[Room]:={...}.
| Out[33]= |  |
A guest can no longer use a "general" room.
| Out[34]= |  |
Placing guests into specific kinds of rooms is no problem. This makes the manager happy, he can write a bill.
| Out[35]= |  |