Tutorial 4: Working with class inheritance

 

On this tutorial, we will learn how to work with classes’ inheritance.

 

Following with the Tastrade sample, and to show how a complete object orientation help us with the application design, we will create a Person class with an Employee subclass and Customer and Supplier classes will reference to a Person instance as a contact.

 

·         Clear your objects instance by typing this in the Command window:

 

 

CLEAR ALL

 

 

·         Open your Classes.PRG file to edit:

 

 

MODIFY COMMAND classes

 

 

·         Add the following classes definitions:

 

 

DEFINE CLASS Person AS Container

      FirstName = ""

      LastName  = ""

      Title     = ""

      Gender    = 0

      BirthDate = {}

ENDDEFINE

 

DEFINE CLASS Employee as Person

      EmployeeID  = 0

      Title       = ""

      HireDate    = {}

      ADD OBJECT Address AS Address

      Group       = 0

      SalesRegion = ""

      Photo       = ""

      Notes       = ""

ENDDEFINE  

 

DEFINE CLASS Supplier AS Container

      SupplierID  = 0

      CompanyName = ""

      ADD OBJECT Contact AS Person

      ADD OBJECT Address AS Address

ENDDEFINE

 

DEFINE CLASS Customer AS Container

      CustomerID  = 0

      CompanyName = ""

      ADD OBJECT Contact AS Person

      ADD OBJECT Address AS Address

      MaxOrderAmt = 0.0000

      MinOrderAmt = 0.0000

      Discount    = 0.00

      SalesRegion  = ""

ENDDEFINE

 

·         And Add the Phone and Fax properties to the existing Address class definition:

 

 

DEFINE CLASS Address AS Custom

      Street      = ""

      City        = ""

      Region      = ""

      PostalCode  = ""

      Country     = ""

      Phone       = ""

      Fax         = ""

ENDDEFINE

 

 

·         Close your Classes.PRG file saving the changes.

 

·         Open the Schema Manager tool

 

·         Open the Tastrade.FDO mapping file

 

·         Now select Parse Class Library… from the Tools menu and select your Classes.PRG file.

 

Your changes are documented and the Schema Manager shows new and modified object-model items in Red and Blue respectively.

 

·         Click to expand the Person class node.

 

You can see how the Employee class is drawn as a child node because of the inheritance relationship.

 

The Person class has been mapped into a Person table and, by default, the Employee class has been mapped into the same Person table because the default option for Class Inheritance Strategy was set to Flat (Horizontal) when we parsed the library file.

 

·         Click on the Employee class node and then click on the Mapping tab on the right panel.

 

You will see that the Inheritance Strategy option is set to Flat Mapping (remember you can change the default option used by FDO at the Main Schema node options).

With a Flat Mapping Inheritance Strategy, all of the properties in the Employee class are mapped as columns added to the Person table. Normally it is the most used option because keeps all data on the same table, thus to retrieve an Employee instance, FDO needs to select just one record from the database.

However, in this case, the Person class will be extensively used by Customer and Supplier entities. In practice, the Person table will contain a lot of records that belong to Person instances and a few records that belong to Employee instances. It is just right but if you are concerned about wasted space in table columns used just by a few records, you can instruct FDO to use a Vertical Inheritance Strategy for the Employee class. Doing so, the Employee subclass will be mapped to its own Employee table with all of its properties as table columns. This way, the person table will contain columns for the Person class attributes only. We optimized database space (normalization) but now an Employee instance uses two records in the database. Anyway, all this work is done by FoxDataObjects at C++ speed so: do not worry.

 

Before doing any change, look at the Relational Model nodes and you will see there is a Person table but not an Employee table.

 

·         Now, change the Inheritance Strategy value to Vertical in the Mapping tab on the Employee class options form.

 

The Relational Model is refreshed. You will find an Employee table as shown in the next figure:

 

 

As you can see in the Object Model, FoxDataObjects mapped all the members automatically.

 

·         Navigate to the Address member in the Customer class and click to select the node.

 

·         Click on the Mappings tab in the right side panel.

 

FoxDataObjects mapped the contained object to a column in the Customer table that wild hold the Object_ID for the address instance contained in the Customer instance; you can rename the column but not the data type because it is entirely managed by FDO.

 

·         Click on the Relationship tab in the right side panel.

 

FoxDataObjects set the Reference Class as Address, also note the Ordinality as been set as Mandatory, the Ownership flag has been set, and both options has been disabled. It is because single references implemented as contained objects always represent an owned relationship that cannot be null and when the container object is removed, all of its contained objects are deleted.

Since FoxDataObjects deduced all the mappings, there are just a few things to tweak:

 

We will change the column data type used to store an Employee picture from Varchar to BLOB.

 

·         Click to expand the Object Model node

 

·         Click to expand the Person class node

 

·         Click to expand the Employee class node

 

·         Click to select the Photo member node

 

·         Select the Mapping tab in the right panel

 

·         Select BLOB from the column Data Type dropdown list

 

We are just done with the mappings.

 

·         Close the Schema Manager and ensure the changes are saved.

 

Let us test our classes!

 

 

Command

Result

 

SET PROCEDURE TO FDO, Classes ADDITIVE

 

 

 

oServer=CREATEOBJECT(“fdoServer”)

 

 

 

oSession=oServer.NewSession(“Tastrade.FDO”)

 

 

 

oEmp.FirstName="Steven"

oEmp.LastName="Buchanan"

oEmp.Title="Sales Manager"

oEmp.BirthDate={03/04/1955}

oEmp.HireDate={02/04/2002}

 

 

 

oEmp.Address.Street="14 Garrett Hill"

oEmp.Address.City="London"

oEmp.Address.PostalCode="SW1 8JR"

oEmp.Address.Country="UK"

oEmp.Address.Phone="(71) 555-4848 "

 

 

 

?oSession.SaveObject(oEmp)

 

 

.T.

 

We created an Employee instance and filled some of its properties. We also filled some of the Address object contained in the Employee instance.

When FoxDataObjects saved the Employee instance, it inserted three records: one into the Person table, one into the Employee table and one into the Address table.

Browse your tables and you will see those records.

 

Do you envisage how powerful it is becoming? You work into your object model and the relational persistence problem is managed by FoxDataObjects. Anyway, you can still access your database records as always, but we will see that on next tutorials.

 

 


< Tutorial 3: Adding behavior and using Events

Home

Tutorial 5: Working with Collections >

 

 

Send feedback on this topic to RunAhead Technologies

For Technical support and product issues please contact us at support@foxdataobjects.com or visit http://www.foxdataobjects.com

 

Copyright (c) 2000-2005 RunAhead Technologies