Creating Classes from Objects
Even if you are going to use objects/classes, you will still need to know how to create classes. You will find that there will be times when you are placing the same function or procedure inside multiple objects. When this happens, you should consider creating a subclass. Creating a subclass is easy. Often, you will find that you have already created an object with functions and procedures that you would like to convert into a subclass. This is quite easy to do.
We will start with a simple example. Let's assume that you wanted all your lists to ring a bell when an item has been selected (users press ENTER) and two bells when they cancel the list (users press ESC). After careful experimentation, you found the following list object did what you wanted.
Object oMyList is a dbModalPanel
// Augment to ring bell once
Procedure OK
Send Bell
Forward Send OK
End_Procedure
// Augment to ring bell twice
Procedure Cancel
Send Bell
Send Bell
Forward Send Cancel
End_Procedure
:
: add additional objects here
:
End_Object
You now need to make this work the same way in all thirty of your list objects. You can choose to cut and paste the OK and Cancel procedures into all thirty objects, or you can make a subclass and base the objects on this class. This is the better solution. A subclass is made as follows:
Class cBellDbModalPanel is a dbModalPanel
// Augment to ring bell once
Procedure OK
Send Bell
Forward Send OK
End_Procedure
// Augment to ring bell twice
Procedure Cancel
Send Bell
Send Bell
Forward Send Cancel
End_Procedure
End_Class
Your object and the thirty other objects would now look like this:
Object oMyList is a cBellDbModalPanel
:
: add additional objects here
:
End_Object
One very important rule about creating a subclass from an object is that all code in the class must be placed inside a function or a procedure. As a rule, any object code that was not placed inside a function or procedure should be placed inside your object constructor, the Procedure Construct_Object.
For example, the code shown below takes the Container class and changes three properties just for one object:
Object oMyContainer is a Container
Set Scope_State to True
Set Attach_Parent_State to True
Set Ring_State to True
:
End_Object
When you set these properties in a class definition, you should not do the following:
// This is wrong!
Class cViewContainer is a Container
Set Scope_State to True
Set Attach_Parent_State to True
Set Ring_State to True
End_Class
This will compile and it might even run. It will definitely not do what you want. All code in a class must be inside a function or a procedure. Place the object code that was not inside a function or a procedure inside Construct_Object. Construct_Object is called when the Object command is executed. Here is how to set these properties correctly in a class definition:
Class cViewContainer is a Container
Procedure Construct_Object
Forward Send Construct_Object
Set Scope_State to True
Set Attach_Parent_State to True
Set Ring_State to True
End_Procedure
End_Class
There is a somewhat similar programming error committed with the End_Construct_Object procedure. Say you set the properties discussed above in Procedure End_Construct_Object, as:
Class cViewContainer is a Container
Procedure End_Construct_Object
Forward Send End_Construct_Object
Set Scope_State to True
Set Attach_Parent_State to True
Set Ring_State to True
End_Procedure
End_Class
This would actually work, but it would make it impossible to set the properties to other values in instances of the new class. Anything you set them to would be canceled by the settings in End_Construct_Object. And no error would be reported at compile or run time. In a subclass of this class, the property-setting code would not even be visible—it would be incorporated with a forward send End_Construct_Object.