As always you can download the project, from here.
And now the Employee class code; the Hat's one in the next.
unit Employee;
{$mode objfpc}{$H+}
interface
uses
Classes,SysUtils,Dialogs,
Hat; //Employee HAS A Hat. Aggregation
type
TEmployee = class //Eployee 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 Class employee can SEE this zone)
//PRIVATE ATTRIBUTES
Id: integer; //Private Object Attribute
Name: string; //Private Object Attribute
Surname: string; //Private Object Attribute
HatList : TList; //List of objects of TDocuments (list of TDocument) Private Object Attribute
//TList is a list of pointers. THats, TObject are pointers! (Casting)
//aggregation is done here !!!
//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 children can SEE this zone)
//We will see this later on the inheritance
public //PUBLIC (Anyone can see this zone)
//PUBLIC ATTRIBUTES
//Id_public: integer; //Public Object Attribute (bad NO encapsulation! Object attributes must be private)
//...
//PUBLIC METHODS
//Constructors (Create the object Employee):
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
function GetHat(index:integer):THat; //Public Object Method
function GetHats():TList; //Public Object Method
procedure SetHat(Hat_:THat); //this function reveals aggregation since in order to add a hat the hat must be created !!!!
procedure DeleteHat(Hat_:THat);
end;
implementation
uses unit1;
var
Counter: integer =0; //Class Attribute SOS !!!
//implementation of the methods here !!!
//Class Method
constructor TEmployee.Create(Name_,Surname_: string); overload;
begin
self.Name:=Name_;
self.Surname:=Surname_;
HatList := TList.Create; //Create the empty hat list !!!
self.Id := GetNextFreeId();
counter:=counter+1;
end;
//Class Method
Destructor TEmployee.Destroy; //override; //not needed here !!!
var i,imax : integer;
begin
imax := self.HatList.Count-1;
if imax>=0 then begin
for i:=imax downto 0 do begin //from the end to the start i delete !!!
//THat(HatList.Items[i]).Destroy; //DO NOT DESTROY THE HAT ! HAT CAN LIVE BY ITSELF (AGGREGATION)!
//the follow is correct to add :
THat(HatList.Items[i]).SetIsAvailable(true);
HatList.Delete(i); //delete documentlist cell
end;
end;
HatList.Free; //Destroy the list !!!
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
self.Name := Name_;
end;
//Object Method
function TEmployee.GetSurname():string;
begin
result := self.Surname;
end;
//Object Method
procedure TEmployee.SetSurname(Surname_:string);
begin
self.Surname := Surname_;
end;
//Object Method
function TEmployee.PrintMe():string;
var i,imax : integer;
semployee, shat :string;
begin
semployee := 'Id : ' + inttostr(self.Id) + '; Name : ' + self.Name + '; Surname : ' + self.Surname + ' ';
imax := self.HatList.Count-1;
if imax>=0 then begin
for i:=0 to imax do begin
shat := shat + THat(HatList.Items[i]).PrintMe + #13#10; //Print each hat
end;
end;
result := semployee + #13#10 + shat;
end;
function TEmployee.GetHat(index:integer):THat;
begin
result := THat(self.HatList.Items[index]);
end;
function TEmployee.GetHats():TList;
begin
result := self.HatList;
end;
procedure TEmployee.SetHat(Hat_:THat);
begin
// i do NOT create the hat
self.HatList.Add(Hat_);
Hat_.SetIsAvailable(false);
end;
procedure TEmployee.DeleteHat(Hat_:THat);
var i,imax : integer;
begin
imax := self.HatList.Count-1;
if imax>=0 then begin
for i:=0 to imax do begin
if THat(HatList.Items[i]).GetName = Hat_.GetName then begin
THat(HatList.Items[i]).Destroy; //Delete hat
HatList.Delete(i); //Delete the cell (hole) of the hatlist
break;
end;
end;
end;
end;
end.