About objects

What an object is

In object-oriented programming, an object is a self-contained module containing state information and associated methods. Most entities in PowerBuilder are objects: visual objects such as windows and controls on windows, nonvisual objects such as transaction and error objects, and user objects that you design yourself.

An object class is a definition of an object. You create an object's definition in the appropriate painter: Window, Menu, Application, Structure, or User Object painter. In the painter, you add controls to be part of the object, specify initial values for the object's properties, define its instance variables and functions, and write scripts for its events and functions.

An object instance is an occurrence of the object created during the execution of your application. Your code instantiates an object when it allocates memory for the object and defines the object based on the definition in the object class.

An object reference is your handle to the object instance. To interact with an object, you need its object reference. You can assign an object reference to a variable of the appropriate type.

System objects versus user objects

There are two categories of objects supported by PowerBuilder: system objects (also referred to as system classes) defined by PowerBuilder and user objects you in define in painters.

System objects

The PowerBuilder system objects or classes are inherited from the base class PowerObject. The system classes are the ancestors of all the objects you define. To see the system class hierarchy, select the System tab in the Browser, select PowerObject, and select Show Hierarchy and Expand All from the pop-up menu.

User objects

You can create user object class definitions in several painters: Window, Menu, Application, Structure, and User Object painters. The objects you define are inherited from one of the system classes or another of your classes.

Some painters use many classes. In the Window and User Object painters, the main definition is inherited from the window or user object class. The controls you use are also inherited from the system class for that control.

About user objects

Two types

There are two major types of user objects: visual and class.

Visual user objects

A visual user object is a reusable control or set of controls that has a certain behavior. There are three types -- standard, custom, and external.

Visual user objects

Description

Standard

Inherited from a specific visual control. You can set properties and write scripts so that the control is ready for use.

It has the same events and properties as the control it is inherited from plus any that you add.

Custom

Inherited from the UserObject system class. You can include many controls in the user object and write scripts for their events.

Each control in the user object has the same events and properties as the controls from which they are inherited plus any that you add.

External

A user object that displays a visual control defined in a DLL. The control is not part of the PowerBuilder object hierarchy. The DLL developer provides information for setting style bits that control its presentation.

Its events, functions, and properties are specified by the developer of the DLL.

An external user object is not the same as an OCX, which you can put in an OLE control.


Class user objects

Class user objects consist of properties, functions, and sometimes events. They have no visual component. There are two types -- standard and custom.

Class user objects

Description

Standard

Inherits its definition from a nonvisual PowerBuilder object, such as the Transaction or Error object. You can add instance variables and functions.

A few nonvisual objects have events to write scripts for these events, you have to define a class user object.

Custom

An object of your own design for which you define instance variables, events, and functions in order to encapsulate application-specific programming in an object.


For information on defining and using user objects, see the Working with User Objects in Users Guide.

Instantiating objects

Classes versus instances

Because of the way PowerBuilder object classes and instances are named, it is easy to think they are the same thing. For example, when you define a window in the Window painter, you are defining an object class.

One instance

When you open a window with the simplest format of the Open function, you are instantiating an object instance. Both the class definition and the instance have the same name. In your application, w_main is a global variable of type w_main:

Open(w_main)

When you open a window this way, you can only open one instance of the object.

Several instances

If you want to open more than one instance of a window class, you need to define a variable to hold each object reference:

w_main w_1, w_2
Open(w_1)
Open(w_2)

You can also open windows by specifying the class in the Open function:

window w_1, w_2
Open(w_1, "w_main")
Open(w_2, "w_main")

For class user objects, you always define a variable to hold the object reference and then instantiate the object with the CREATE statement:

uo_emp_data uo_1, uo_2
uo_1 = CREATE uo_emp_data
uo_2 = CREATE uo_emp_data

You can have more than one reference to an object. You might assign an object reference to a variable of the appropriate type, or you might pass an object reference to another object so that it can change or get information from the object.

For more information about object variables and assignment, see User objects that behave like structures.

Using ancestors and descendants

descendant objects

In PowerBuilder, an object class can be inherited from another class. The inherited or descendant object has all the instance variables, events, and functions of the ancestor. You can augment the descendant by adding more variables, events, and functions. If you change the ancestor, even after editing the descendant, the descendant incorporates the changes.

Instantiating

When you instantiate a descendant object, PowerBuilder also instantiates all its ancestor classes. You do not have programmatic access to these ancestor instances, except in a few limited ways, such as when you use the scope operator to access an ancestor version of a function or event script.

Garbage collection

What garbage collection does

The PowerBuilder garbage collection mechanism checks memory automatically for unreferenced and orphaned objects and removes any it finds, thus taking care of most memory leaks. You can use garbage collection to destroy objects instead of explicitly destroying them using the DESTROY statement. This lets you avoid runtime errors that occur when you destroy an object that was being used by another process or had been passed by reference to a posted event or function.

When garbage collection occurs

Garbage collection occurs:

  • When a reference is removed from an object

    A reference to an object is any variable whose value is the object. When the variable goes out of scope, or when it is assigned a different value, PowerBuilder removes a reference to the object, counts the remaining references, and destroys the object if no references remain.

  • When the garbage collection interval is exceeded

    When PowerBuilder completes the execution of a system-triggered event, it makes a garbage collection pass if the set interval between garbage collection passes has been exceeded. The default interval is 0.5 seconds. The garbage collection pass removes any objects and classes that cannot be referenced, including those containing circular references (otherwise unreferenced objects that reference each other).

    When you post an event or function and pass an object reference, PowerBuilder adds an internal reference to the object to prevent it from being collected between the time of the post and the actual execution of the event or function. This reference is removed when the event or function is executed.

Exceptions to garbage collection

There are a few objects that are prevented from being collected:

  • Visual objects

    Any object that is visible on your screen is not collected because when the object is created and displayed on your screen, an internal reference is added to the object. When any visual object is closed it is explicitly destroyed.

  • Timing objects

    Any Timing object that is currently running is not collected because the Start function for a Timing object adds an internal reference. The Stop function removes the reference.

  • Shared objects

    Registered shared objects are not collected because the SharedObjectRegister function adds an internal reference. SharedObjectUnregister removes the internal reference.

Controlling when garbage collection occurs

Garbage collection occurs automatically in PowerBuilder, but you can use the functions GarbageCollect, GarbageCollectGetTimeLimit, and GarbageCollectSetTimeLimit to force immediate garbage collection or to change the interval between reference count checks. By setting the interval between garbage collection passes to a very large number, you can effectively turn off garbage collection.

User objects that behave like structures

In PowerBuilder, a nonvisual user object can provide functionality similar to that of a structure. Its instance variables form a collection similar to the variables for the structure. In scripts, you use dot notation to refer to the user object's instance variables, just as you do for structure variables.

Advantages of user objects

The user object can include functions and its own structure definitions, and it allows you to inherit from an ancestor class. None of this is possible with a structure definition.

Memory allocation differences

Memory allocation is different for user objects and structures. An object variable is a reference to the object. Declaring the variable does not allocate memory for the object. After you declare it, you must instantiate it with a CREATE statement. Assignment for a user object is also different (described in Assignment for objects and structures).

Autoinstantiated objects

If you want a user object that has methods and inheritance but want the memory allocation of a structure, you can define an autoinstantiated object.

You do not have to create and destroy autoinstantiated objects. Like structures, they are created when they are declared and destroyed when they go out of scope. However, because assignment for autoinstantiated objects behaves like structures, the copies made of the object can be a drawback.

To make a custom class user object autoinstantiated, select the Autoinstantiate check box on the user object's property sheet.