# Directives

DEF CLASS | Define Object Class

## Formats

DEF CLASS class$ | [UNIQUE] [ACCEPT PROPERTIES] [ACCEPT UNDEFINED]
| [CREATE label [REQUIRED]]
| [DELETE label [REQUIRED]]

Where:

class$ | Class name that will refer to this type of object.
ACCEPT PROPERTIES | Optional phrase that indicates that object properties can be created dynamically. See Dynamic Property Creation.
ACCEPT UNDEFINED | Optional phrase similar to ACCEPT PROPERTIES functionality except that ACCEPT PROPERTIES will not allow you to read a property that has never been defined whereas using ACCEPT UNDEFINED instead will return a null string or zero. #### Note: ACCEPT UNDEFINED only applies the top level class; therefore, this option is not inheritable using the LIKE directive.
CREATE label | Optional keyword with statement label for override of ON_CREATE logic.
DELETE label | Optional keyword with statement label for override of ON_DELETE logic.
REQUIRED | Optional keyword for either the CREATE or DELETE option that mandates that this object class' create/delete logic must be included even when the object is inherited.
UNIQUE | Optional keyword that, if specified, indicates that there will only be one instance of this class in the system ever. Any attempt to create multiple instances will return the handle to the already existing object.

(The ACCEPT UNDEFINED option was added in PxPlus 2021.)

## Description

Use the DEF CLASS directive in Object Oriented Programming (OOP) to declare the start of an object definition. It defines the name of the object, and it can be used to override object creation and deletion logic.

The value of class$ specifies the class name that will refer to this type of object. Class names are case insensitive, and forward/backward slashes are considered equivalent. Duplicate names are not allowed within the system.

An object declared as UNIQUE will have a single instance created, and any subsequent attempt to create an instance returns the same object identifier and increments the object reference count by one.

By default, an object can have ON_CREATE and/or ON_DELETE logic defined. You can override this by specifying new label names for the creation/deletion logic via CREATE label and DELETE label clauses in the class definition. Normally, object creation/deletion logic is invoked when an object of this specific class is created/destroyed. That means if you have ON_CREATE logic for an object A and object B inherits it, then the ON_CREATE for object A will not be executed on creation of object B. You can force creation and/or deletion logic to be executed on inheritance by including the keyword REQUIRED.

In terms of precedence, if an object inherits another object that has creation logic, the creation logic for the inherited object is performed first; e.g. if object C inherited object B which inherited object A, then the ON_CREATE in object A would be performed first, followed by object B's and finally object C's. (Deletion logic is performed in the opposite order).

## Defining an Object

Fundamentally, an object consolidates data (properties) and functions (methods) into a single unit. The names assigned to properties and methods within the object are unique within the object; i.e. different objects can have data elements or functions of the same name. The names relate only to the object and not to anything else.

This single unit is used in an application to simplify design, coding and testing. All references to an object are controlled through a pointer called the object identifier.

In order to use an object, you must first define its characteristics. Each object is defined with a DEF CLASS statement and a combination of PxPlus OOP directives. DEF CLASS is followed immediately by the directives that describe the object.

> def class "class"
> property prop1, prop2, ...
> local prop1, prop2, ...
> function method (param) do_method
> like "otherclass"
> program "interface_prog"
> precision nnn
> end def

The definition begins with the DEF CLASS directive at the beginning and concludes with the END DEF directive at the end.

## Dynamic Property Creation

If the ACCEPT PROPERTIES clause is declared on the class definition, external programs can dynamically create properties within any instance of the class merely by assigning the property a value. Once a property is dynamically created, it will be present in the property list returned in the '* property list string.

Example:

> def class "params" accept properties
> end def
> ->a=new("params")
> ->?a'*
> ->a'company$="Joes Crabs"
> ->a'City$="Any town"
> ->?a'*
> CITY$,COMPANY$,
> ->print a'city$
> Any town

In addition, any instance of an object can add properties to itself using the ADD PROPERTY directive.

#### Note:
ACCEPT PROPERTIES will not allow you to read a property that has never been defined whereas using ACCEPT UNDEFINED instead will return a null string or zero.

(Dynamic property creation was added in PxPlus v8.01.)

## See Also

DROP CLASS Delete Class Definition
DROP OBJECT Delete Object
FUNCTION Declare Object Method
LIKE Inherit Properties
LOAD CLASS Pre-Load Class Definition
LOCAL Designation of Local Data
PROGRAM Create/Assign Program File
PROPERTY Declare Object Properties
RENAME CLASS Change Name of Class
STATIC Add Local Properties at Run Time
NEW( ) Create New Object
REF( ) Control Reference Count

## Example

The following is an example of the definition of the object "Customer":

> def class "Customer"
> property NAME$ set CHG_NAME ! Run CHG_NAME when NAME$ changes
> property Cust_No$,ADDR$,CITY$,SALESMAN$,AMT_OWING
> local FileNo ! File channel number
> !
> function FIND(KeyValue$)
> enter KeyValue$
> read (FileNo,key=KeyValue$) ! Loads all the variables
> return 1
> !
> function NEXT()
> read (FileNo,end=*next);
> return 1
> return 0
> !
> function UPDATE()
> write (FileNo)
> return 1
> !
> end def
> !
> CHG_NAME:
> enter NEW_NAME$
> local NEW_NAME_LEN=len(NEW_NAME$)
> if NEW_NAME_LEN<1 or NEW_NAME_LEN>40 \
> then exit 41 ! Prevent empty names and too long names
> NAME$=NEW_NAME$
> return
> !
> ON_CREATE:
> open object (hfn,iol=*)"ARCUST"
> FileNo=lfo
> return

The object can be used as follows:

> C=new("Customer")
> input "Customer #",X$:"000000"
> C'Find(X$,err=Bad_Cust)
> !
> while 1
> newname$=C'Name$ ! INPUT requires a true variable
> input edit "Name:",newname$
> C'Name$=newname$
> !
> C'Update()
> !
> input "Do you want to edit the next customer (yes/no)?",yesno$
> if lcs(yesno$)="no" \
> then break \
> else sts=C'Next();
> if sts=0 \
> then print "Last customer edited.";
> break
> !
> wend
> !
> drop object C
> end
> !
> Bad_Cust:
> print "Record not found"
> drop object C
> end