Object Model in Delphi

The Delphi language is a set of object-oriented extensions to standard Pascal. Objectoriented programming is an extension of structured programming that emphasizes code reuse and encapsulation of data with functionality.

Once you define a class, you and other programmers can use it in different applications, thus reducing development time and increasing productivity. A class is a data type that encapsulates data and operations on data in a single unit. Before object-oriented programming, data and operations (functions) were treated as separate elements.

An object is an instance of a class. That is, it is a value whose type is a class. The term object is often used more loosely in this documentation and where the distinction between a class and an instance of the class is not important, the term “object” may also refer to a class.

You can begin to understand objects if you understand Pascal records or structures in C. Records are made of up fields that contain data, where each field has its own type. Records make it easy to refer to a collection of varied data elements.

Objects are also collections of data elements. But objects—unlike records—contain procedures and functions that operate on their data. These procedures and functions are called methods.

An object’s data elements are accessed through properties. The properties of many Delphi objects have values that you can change at design time without writing code. If you want a property value to change at runtime, you need to write only a small amount of code.

The combination of data and functionality in a single unit is called encapsulation. In addition to encapsulation, object-oriented programming is characterized by inheritance and polymorphism. Inheritance means that objects derive functionality from other objects (called ancestors); objects can modify their inherited behavior.

Polymorphism means that different objects derived from the same ancestor support the same method and property interfaces, which often can be called interchangeably.

When you create a new project, the IDE displays a new form for you to customize. In the Code editor, the automatically generated unit declares a new class type for the form and includes the code that creates the new form instance. The generated code for a new Windows application looks like this:

unit Unit1; interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm){ The type declaration of the form begins here } private { Private declarations } public { Public declarations } end;{ The type declaration of the form ends here } var Form1: TForm1; implementation{ Beginning of implementation part } {$R *.dfm} end.{ End of implementation part and unit}

The new class type is TForm1, and it is derived from type TForm, which is also a class. A class is like a record in that they both contain data fields, but a class also contains methods—code that acts on the object’s data.

So far, TForm1 appears to contain no fields or methods, because you haven’t added any components (the fields of the new object) to the form and you haven’t created any event handlers (the methods of the new object). TForm1 does contain inherited fields and methods, even though you don’t see them in the type declaration.

This variable declaration declares a variable named Form1 of the new type TForm1.

var Form1: TForm1;

Form1 represents an instance, or object, of the class type TForm1. You can declare more than one instance of a class type; you might want to do this, for example, to create multiple child windows in a Multiple Document Interface (MDI) application. Each instance maintains its own data, but all instances use the same code to execute methods.

Although you haven’t added any components to the form or written any code, you already have a complete GUI application that you can compile and run. All it does is display a blank form. Suppose you add a button component to this form and write an OnClick event handler that changes the color of the form when the user clicks the button.

When the user clicks the button, the form’s color changes to green. This is the eventhandler code for the button’s OnClick event:

procedure TForm1.Button1Click(Sender: TObject); begin Form1.Color := clGreen; end;

Objects can contain other objects as data fields. Each time you place a component on a form, a new field appears in the form’s type declaration. If you create the application described above and look at the code in the Code editor, this is what you see:

unit Unit1; interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) Button1: TButton;{ New data field } procedure Button1Click(Sender: TObject);{ New method declaration } private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject);{ The code of the new method } begin Form1.Color := clGreen; end; end.

TForm1 has a Button1 field that corresponds to the button you added to the form. TButton is a class type, so Button1 refers to an object. All the event handlers you write using the IDE are methods of the form object.

Each time you create an event handler, a method is declared in the form object type. The TForm1 type now contains a new method, the Button1Click procedure, declared in the TForm1 type declaration. The code that implements the Button1Click method appears in the implementation part of the unit.