Classes and Objects

In this section:

Most application development is modular: the developer creates complex systems comprised of smaller parts. In conventional "procedural" development, these modules are processes (such as procedures), and data is defined within each process. In object-oriented development, the modules are models of real-world objects (such as a customer or a shipping order), and both data and processes are defined within each object. The object encapsulates the data and processes.

For example, if you are developing an order fulfillment system for a mail-order clothing business, the objects might include customers, orders, and stock items. A customer object's data might include the customer's ID code, phone number, and order history; the customer's processes might include a function that adds the customer to a new mailing list, a function that updates the customer's contact information, and a function that places an order for the customer.

Object-oriented development—because it models the real-world objects with which your enterprise deals, and encourages you to reuse application logic in a variety of ways—is a more efficient way to develop applications. Maintain enables you to create applications using object-oriented development, conventional development, or a hybrid of these two methods, providing you with a flexible development path.


Top of page

x
What Are Classes and Objects?

Most applications need many objects of the same type. For example, if your business has 500 customers, you need one object to represent each customer. No one would want to design a customer object 500 times; clearly, you need a template that defines all customer objects, so that you can design the template once, and use it often. For example, you would use the template each time you create a new customer object to represent a new customer.

An object's template is called its class. Each object is an instance of a class. In other words, the class defines the type of object. In fact, when you create a class, the class becomes a new data type. Just as you can use a built-in data type, such as integer or alphanumeric, to define a simple variable, you can use a class data type to define an object.



Example: Comparing Classes and Built-in Data Types

Maintain supports two kinds of data types: built-in data types, and classes that you define yourself. For example, just as you can use the built-in data type alphanumeric to define a customer ID code

DECLARE CustID/A8;

you can use the class RetailCustomer to define an object as a customer:

DECLARE CustSmit8942/RetailCustomer;

Top of page

x
Class Properties: Member Variables and Member Functions

You define a class by describing its properties. Classes have two kinds of properties:



Example: Member Variables for a Customer Class

An application for a mail-order clothing business has defined a customer class named Customer. The member variables in the class might include the customer's code, phone number, and most recent order number:

DESCRIBE Customer =
(IDcode/A6,
 Phone/I10,
 LastOrder/A15);
 .
 .
 .
ENDDESCRIBE

After declaring a new customer object for the customer Frances Smith

DECLARE CustFrSmith/Customer;

you could assign a value to Frances Smith's IDcode member variable:

DECLARE CustFrSmith.IDcode = GetNewCustCode();

Each object can have different values for its member variables; for example, in this case, each customer will have a different ID code.



Example: Member Functions for a Customer Class

An application for a mail-order clothing business has defined a customer class named Customer. The member functions in the class might include a function that adds the customer to a new mailing list, a function that updates the customer's contact information, and a function that places an order for the customer:

DESCRIBE Customer = 
(IDcode/A6,
 Phone/I10,
  .
  .
  .
 LastOrder/A15);
 CASE AddToList TAKES Name/A25, Address/A50, IDcode/A6;
  .
  .
  .
 ENDCASE
 CASE UpdateContact ... 
 CASE PlaceOrder ...
ENDDESCRIBE

After declaring a new customer object for the customer Frances Smith

DECLARE CustFrSmith/Customer;

you could add Frances Smith to the mailing list using the AddToList member function:

CustFrSmith.AddToList();

Each object has the same member functions, and so the same behavior; for example, in this case, each customer will be added to the mailing list using the function.


Top of page

x
Inheritance: Superclasses and Subclasses

If you want to create a new class that is a special case of an existing class, you could derive it from the existing class. For example, in a human resources application, a class called Manager could be considered a special case of a more general class called Employee: all managers are employees, and posses all employee attributes, plus some additional attributes unique to managers. The Manager class is derived from the Employee class, so Manager is a subclass of Employee, and Employee is the superclass of Manager.

A subclass inherits all of its superclass's properties (that is, it inherits all of the superclass's member variables and member functions). When you define a subclass, you can choose to override some of the inherited member functions; this means that you can recode them to suit the ways in which the subclass differs from the superclass. You can also add new member functions and member variables that are unique to the subclass.


Top of page

x
Defining Classes

How to:

Before you can declare an object (an instance of a class), your procedure must have a class definition for that type of object. If the class:



x
Syntax: How to Define a Class or Subclass

You can define classes (including subclasses) using the DESCRIBE command. You must issue the DESCRIBE command outside of a function—for example, at the beginning of the procedure prior to all functions. (Functions are also known as cases.)

DESCRIBE classname = ([superclass +] memvar/type [, memvar/type] ...) [;]
[memfunction 
[memfunction] ...
ENDDESCRIBE]

where:

classname

Is the name of the class that you are defining. The name is subject to the Maintain language's standard naming rules; for more information, see Specifying Names.

superclass

Is the name of the superclass from which you wish to derive this class. Include only if this definition is to define a subclass.

memvar

Names one of the member variables in the class. The name is subject to the Maintain language's standard naming rules; for more information, see Specifying Names.

type

Is a data type (a built-in format or a class).

memfunction

Defines one of the member functions in the class. Member functions are defined the same way as other Maintain functions, using the CASE command; for more information, see CASE.

;

Terminates the definition if the definition omits member functions. If it includes member functions, the semicolon is omitted and the ENDDESCRIBE command is required.

ENDDESCRIBE

Ends the class definition if it includes member functions. If it omits member functions, the ENDDESCRIBE command must also be omitted, and the definition must be terminated with a semicolon.


Top of page

x
Reusing Classes in Class Libraries

How to:

You can define a class once, but use it in multiple Maintain procedures, by storing its definition in a class library. A library is a kind of non-executable procedure in which you can store class definitions (as well as Maintain functions); you then import the library into each Maintain procedure in which you want to use those classes.



x
Procedure: How to Create a Class Library

To create a class library:

  1. Create a new Maintain procedure (that is, a FOCEXEC containing only MAINTAIN and END commands).
  2. Create class definitions in the procedure. See Defining Classes for more information about creating class definitions

    or

    Copy class definitions from other procedures and paste them into this procedure.

You can nest libraries to any depth using the MODULE IMPORT command. For example, to nest library B within library A, issue a MODULE IMPORT B command within library A. For more information about the MODULE IMPORT command, see MODULE.

Note that a library cannot contain an explicit Top function.



x
Syntax: How to Import a Class Library

You can use the MODULE command to import libraries containing class definitions so that the current procedure can use those classes. (Libraries can also contain other source code, such as function definitions.) The syntax is

MODULE IMPORT (library_name [, library_name] ... );

where:

library_name

Is the name of the Maintain procedure that you wish to import as a source code library. Specify its file name without an extension.

The library is a FOCEXEC file, and its naming and allocation requirements are those for FOCEXEC files generally.

The MODULE command must immediately follow the procedure's MAINTAIN command.


Top of page

x
Declaring Objects

How to:

Once a class definition exists, you can declare objects of that class. This is identical to declaring the simple variables of a built-in data type. You declare objects using the DECLARE command.



x
Syntax: How to Declare an Object

You can declare a local or global object using the DECLARE command. To make the declaration:

To declare an object using the DECLARE command, use this syntax

DECLARE
[(]  
objectname/class [= expression];
.
.
.
[)]

where:

objectname

Is the name of the object that you are creating. The name is subject to the Maintain language's standard naming rules; for more information, see Specifying Names.

class

Is the name of the class of which this object will be an instance.

expression

Is an optional expression that will provide the object's initial value. If the expression is omitted, the object's initial value is the default for that data type: a space or null for date and alphanumeric data types, and zero or null for numeric data types.

( )

Groups a sequence of declarations into a single DECLARE command. The parentheses are required for groups of local declarations; otherwise they are optional.


Information Builders