
Object Oriented Programming with Delphi
1. Intro
For years I've been practising OOP with Delphi even though I didn't know the ins- and
out of object oriented programming. I was doing alright but I missed the fun side of
Delphi because I was only using standard and vendor components.
Now my eyes are opened and I want to share my growing knowledge with this paper.
This paper is about : Object Oriented Programming.
In following papers I will discover the Delphi VCL, and even develop own components.
For this paper you need a little Delphi experience as described above.
2. Objects and Classes
2.1 OOP
Until the introduction of OOP in Pascal, version 5.5 I believe, datatype record
was the datatype which has the most in common with today's objects.
A record is a datatype that contains a number of fields.
The fields are the attributes of the record and they define the record.
An object is in fact also a record, but an object has also methods.
An object contains attributes (fields) and methods.
Methods are procedure and functions which belong to the object.
2.2 From class to object
A class is a defined datatype with status and behaviour.
An object is an instance of a class.
Just the same as declaring a variable, for example Var I : Integer; I is the instance of
datatype integer.
In other words, the class is the receipt and the object is the cake.
In Delphi a Class always start with the capital letter T. (this is a convention)
var car : TVerhicle;
Car is the object.
Delphi works with the object referential model so in fact Car is a pointer to the object.
This is essential in Object Pascal.
2.3 What makes a programming language object oriented ?
De four most important OOP features are :
Modelling the real world.
Encapsulation of data and objects. Also called information hiding.
The possibility to inherit data and methods from a higher class.
The possibility of "late binding" in runtime.
The called method (the address of the called method) is determined at runtime.
This four main features will be discussed further on.
2.4 The class definition
How is a class declared :
type
TForm1 = class (Form)
{List with objects which the class owns for example buttons on the form}
private
{Private declarations}
public
{public declarations}
end;
2.5 Exploring the four OOP features
In this paragraph we will explore the above mentioned four most important OOP features.
2.5.1 Abstraction
This is the possibility of a OOP language to model the real world.
In other words, the programs that we write own a model of a real world event.
2.5.2 Encapsulation
Encapsulation, information hiding, is a very important OOP feature.
As you can see in the class definition above methods and field can be declared as follows
:
Fields and methods are only available for the own unit and hidden for other units.
Fields and methods can be used by every unit which has this unit in its uses clause.
Fields and methods are only available for the current class and his subclasses.
What is the benefit of encapsulation ?
If you change something in the private part of the class then this will have no effect on
the program which uses the class.
The main program doesn't need a recompilation because it isn't aware of what is happening
inside the used class.
Scooping of variables
Passing variables from one unit to the other can be done on different manners :
This way is not advisable because the variable applies to the whole application and you can never be sure of his value.
By declaring your variable in the private part of the object. (mostly this will be a
form)
You can read and write the variable with public declared methods.
An example :
type
TForm1 = class (Tform)
...........{controls here}
private
{Private declarations}
MyCounter : Integer;
public
{public declarations}
procedure SetMyCounter ( I : Integer);
function GetMyCounter : Integer;
end;
procedure TForm1.SetMyCounter ( I : Integer );
begin
MyCounter := I;
end;
function TForm1.GetMyCounter : Integer;
begin
Result := MyCounter;
end;
Tip : Don't forget to use class completion ! (Control-shift-C)
An even better way is to do it with properties, we will discuss this in a next paper.
2.5.3 The key self
Before we start discussing inheritance we will first take a good look at methods.
Methods have an implicit parameter, or reference to the current object.
Inside the method this is realised by the key self.
Self.MyCounter :=2;
Watch out : We don't use the key self never in this way.
We use the key self if we want to create controls or components (dynamically) in
runtime.
The owner must be specified, and that is just what the key self does.
Creating components in runtime :
Suppose in object TForm1 we want to create a new form "a" :
a:=TForm.Create(self);
a.show;
self directs to the object which does the call to the method, in this case this is
TForm1
and this is the owner.
If you create a control, like a button, you must also specify a parent.
the button must know where to draw itself.
b : Tbutton;
b := TButton.Create(self);
b.parent := self;
The method create is the so called constructor of the object and is called
to preserve memory to the object.
A constructor can also be used to initialise the object.
2.5.4 Overload methods and constructors
Methods and constructors can be overload . This means that a specific
method
multiple times may be declared inside a unit if the key Overload; is used behind
the method.
The methods must also have different parameters.
The compiler uses the parameters to obtain which method must be called.
The following declaration are possible :
Constructor Create; Overload;
Constructor Create ( Counter : Integer); Overload;
2.5.5 Inheritance
Inheritance is a important OOP feature. It allows inheritance among classes.
This is often called subclassing.
At the start of a new project ( in Delphi) inheritance is used :
TForm1 = class (TForm)
The new form TForm1 inherits all features and methods from TForm.
Compatibility of types
Here an other example of inheritance :
TMotorVehicle = class;
TMotorCycle = Class (TMotorVehicle)
TMotorCycle inherits all methods and properties of TMotorVehicle.
The following declaration can now be done :
MyMotorVehicle := MyMotorCycle;
The other way around is absolute wrong a MotorCycle can't be a
MotorVehicle.
You can always use a object from a new born class if you expect a an object from a parentclass.
2.5.6 Polymorphism
With polymorphism we are going to use advanced OOP techniques.
Polymorphism allows Late binding , in other words the address of the called
method
is determined in runtime.
Normal procedure and functions use static binding where the compiler
determines the memory address.
MotorVehicle from above could be, in runtime, of type TMotorVehicle or
TMotorCycle.
type
TMotorVehicle = class;
Public
Function Starten : Boolean; Virtual;
end;
type
TMotorCycle = class (TMotorVehicle);
Public
function Starten : Boolean; Override;
end;
MyVehicle could be of type TMotorVehicle or TMotorCycle .
The key virtual allows overriding of the method Starten when MyMotorVehicle
is of type TMotorCycle so that the function
Starten from TMotorCycle is called.
We can conclude that MyVehicle.Starten compatible is with all future subclasses if
TMotorVehicle.
Recalling, redefine and reintroducing of methods
Recalling a method means that virtual declared methods in the mainclass can be recalled
by override in the subclass, and
also extra code could be added.
MyClass = Class;
Procedure DoIt; Virtual;
Mysubclass = Class (MyClass);
Procedure DoIt; Override;
Recalling :
Procedure MySubClass.DoIt;
Begin
// The new code
Inherited DoIt; //This function calls Procedure
MijnClass.DoIt aan.
end;
A static method (not virtual) can be redefined by adding it to the subclass without
further specifications.
Virtual Methods in the base class can be recalled by overloading. (different parameters)
the compiler however generates
an error : Method hides virtual method of base type
To overcome this error the key Reintroduce must be used.
Procedure MySubclass.DoIt; reintroduce; overload;
2.5.7 Runtime type information
With RTTI classes can test with classes on their existence using the operators is and as.
If MyVehicle is TMotorCycle then..........
(MyVehicle as TMotorCycle).Start; (This is in fact a TypeCast)
This expressions work like booleans and they are true or false.
For this far theory OOP.