Take your time to understand this first OOP step, because it's very important.
With the following articles we'll go more deeply, always keeping the employee example as glue over the whole discussion.
Here the code of Employee class:
unit Employee; {$mode objfpc}{$H+} interface uses Classes,SysUtils,Dialogs; type TEmployee = class //Employee is a CLASS and is child of TObject (inherited ) //All delphi classes have TObject as root father. This is not true in C++ //Thats why in delphi the Multiple inheritance DOES NOT EXIST //Every class has at MAX ONE Father in Delphi //We have : //1. Class Attributes (var ...) //2. Class Methods (constructors, destructor, class static) //3. Object Attributes (id,name...) //4. Object Methods (Get,Set...) private //PRIVATE ZONE (Only the employee can SEE this zone) //PRIVATE ATTRIBUTES Id: integer; //Private Object Attribute Name: string; //Private Object Attribute Surname: string; //Private Object Attribute //PRIVATE METHODS //procedure Fake(); //Private Object Method //... class function GetNextFreeId(): integer; //Private Class Method (class->static in c++) protected //PROTECTED ZONE (Only the Class employee and his childs can SEE this zone) //We will see this later on the inheritence public //PUBLIC (Anyone can see this zone) //PUBLIC ATTRIBUTES //Public Object Attribute (bad NO incapsulation! //Id_public: integer; Object attributes must be private) //... //PUBLIC METHODS //Constructors (Create the oblect Employee): constructor Create(); overload; //Public Class Method constructor Create(Name_,Surname_ : string); overload; //Public Class Method //The Overload allows you to have different versions of the //same named function/procedure with different arguments //OVERLOAD : SAME NAME OF FUNCTION WITH DIFFERENT ARGUMENTS IN THE SAME CLASS //Destructor (can be only ONE) (Destroy the object Employee) Destructor Destroy; override; //Public Class Method //The Override must be specified since we are overriding the virtual TObject destroy method. //At the end of a destructor, you should call Inherited to invoke the parent destructor. //OVERRIDE : SAME NAME OF FUNCTION WITH SAME ARGUMENTS IN DIFFERENT CLASSES class function CountEmployees(): integer; //Public Class Method (class->static in c++) function GetId():integer; //Public Object Method procedure SetId(Id_:integer); //Public Object Method function GetName():string; //Public Object Method procedure SetName(Name_:string); //Public Object Method function GetSurname():string; //Public Object Method procedure SetSurname(Surname_:string); //Public Object Method function PrintMe():string; //Public Object Method end; implementation uses unit1; // i use the unit 1 in order to get its public functions var Counter: integer =0; //Class Attribute !!! //implementation of the methods here !!! //Class Method constructor TEmployee.Create(); overload; begin self.Name:='Default Name'; // self is "this" in c++ and gives the pointer of the object. Using the dot(.) makes dereference self.Surname:='Default Surname'; // In c++ is traduced to : this->name OR (this*).name self.Id := GetNextFreeId(); // For this reason i add the "self" at the objects. By doing this i can distinguish them from the class methods! counter:=counter+1; end; //Class Method constructor TEmployee.Create(Name_,Surname_ : string); overload; // we write "name_" and not "name" since we use "name" as atribute of the class begin Name:=Name_; // works fine without the self because "name_" is defined differenly from "name" self.Surname:=Surname_; self.Id := GetNextFreeId(); counter:=counter+1; end; //Class Method Destructor TEmployee.Destroy; //override; //not needed here !!! begin counter:=counter-1; showmessage('Employee with Id ' + inttostr(self.Id) + ', Name ' + self.Name + ', Surname ' + self.Surname + ' is deleted'); //Self->This in c++ inherited; // Always call the parent destructor after running your own code end; //Class Method class function TEmployee.GetNextFreeId(): integer; var imax :integer; begin imax := counter-1; //TList start from a[0] etc... if imax <> -1 then begin result := Form1.getEmployee(imax).GetId + 1; //Last element has the higher id since //i always add elements at the last position end else result := 1; end; //Class Method class function TEmployee.CountEmployees(): integer; begin result := counter; end; //Object Method function TEmployee.GetId():integer; begin result := self.Id; end; //Object Method procedure TEmployee.SetId(Id_:integer); begin self.Id := Id_; end; //Object Method function TEmployee.GetName():string; begin result := self.Name; end; //Object Method procedure TEmployee.SetName(Name_:string); begin Name := Name_; end; //Object Method function TEmployee.GetSurname():string; begin result := self.Surname; //result is "return" in c++ end; //Object Method procedure TEmployee.SetSurname(Surname_:string); begin self.Surname := Surname_; end; //Object Method function TEmployee.PrintMe():string; begin result:= 'Id : ' + inttostr(self.Id) + '; Name : ' + self.Name + '; Surname : ' + self.Surname; end; end.
That's all for now!
Thank you, and see you on next article!