Array – Create an instance from a class array

My class definition is:

TAnimal = class(TInterfacedObject)
public
constructor Create; overload;
constructor Create(param: string); overload;
end;

IAnimal = interface
procedure DoSomething;
end;

TDog = class(TAnimal, IAnimal)
public
procedure DoSomething;
end;

TCat = class(TAnimal, IAnimal)
public
procedure DoSomething;
end;

Sample code:

procedure TForm1.DogButtonPressed(Sender: TObject); 
var
myDog: TDog;
I: Integer;
begin
myDog := TDog.Create('123');
I := Length (myQueue);
SetLength(myQueue, I+1);
myQueue[I] := TDog; //Probably not the way to do it...??
end;< br />
procedure TForm1.CatButtonPressed(Sender: TObject);
var
myCat: TCat;
I: Integer;
begin
myCat := TCat.Create('123');
I := Length(myQueu e);
SetLength(myQueue, I+1);
myQueue[I] := TCat; //Probably not the way to do it...??
end;

procedure TForm1.OnProcessQueueButtonPressed(Sender: TObject);
var
MyInterface: IAnimal; //Interface variable
I: Integer;
begin
for I := Low(myQueue) to High(myQueue) do
begin
MyInterface := myQueue[I].Create('123'); //Create instance of relevant class
MyInterface .DoSomething;
end;
end;

So, suppose you have a form with three buttons. The “dog” button, the “cat” button and the “processing queue” button When you press the “dog” button or “cat” button, the related class will be added to the array to act as a queue. Then press the “Process Queue” button, the program will step through the array, create objects of related classes, and then call The interface methods implemented in this class. Remember my sample code, how to implement it?

The obvious way is to add the class name as a string to the string array, and then use the if statement in the OnProcessQueueButtonPressed process, for example:

procedure TForm1.OnProcessQueueButtonPressed(Sender: TObject);
var
MyInterface: IAnimal; //Interface variable
I: Integer;
begin
for I := Low(myQueue ) to High(myQueue) do
begin
if myQueue[I] ='TDog' then
MyInterface := TDog.Create('123');
if myQueue[I ] ='TCat' then
MyInterface := TCat.Create('123');
MyInterface.DoSomething;
end;
end;

I Try to avoid this, because every time I add a new class, I have to remember to add an if block for the new class.

You can use class reference to do this. Define the class reference type as follows:

type
TAnimalClass = class of TAnimal;

And arrange TAnimal support interface:

type
IAnimal = interface
procedure DoSomething;
end;

TAnimal = class(TInterfacedObject, IAnimal)
publi c
constructor Create; overload;
constructor Create(param: string); overload;
procedure DoSomething; virtual; abstract;
end;

TDog = class(TAnimal)
public
procedure DoSomething; override;
end;

TCat = class(TAnimal)
public
procedure DoSomething ; override;
end;

Using arrays can lead to code confusion. It is better to use list objects.

var
myQueue: TList;

Now you can write the following code:

procedure TForm1.DogButtonPressed(Sender: TObject);
begin
myQueue.Add(TDog);
end;

procedure TForm1.CatButtonPressed(Sender: TObject);
begin
myQueue.Add(TCat) ;
end;

procedure TForm1.OnProcessQueueButtonPressed(Sender: TObject);
var
AnimalClass: TAnimalClass;
Animal: IAnimal;
begin
for AnimalClass in myQueue do
begin
Animal := AnimalClass.Create('123');
Animal.DoSomething;
end; myQueue.Clear;
end;

You need to create and destroy instances of myQueue in the appropriate locations. I assume you already know how to do this.

Of course, using class references in this way makes the interface meaningless.

My class definition is:

TAnimal = class(TInterfacedObject)
public
constructor Create; overload;
constructor Create(param: string); overload;
end;

IAnimal = interface
procedure DoSomething;
end;

TDog = class(TAnimal, IAnimal)
public
procedure DoSomething;
end;

TCat = class(TAnimal, IAnimal)
public< br /> procedure DoSomething;
end;

Sample code:

procedure TForm1.DogButtonPressed(Sender: TObject);
var
myDog: TDog;
I: Integer;
begin
myDog := TDog.Create('123');
I := Length(myQueue);
SetLength(myQueue, I+1);
myQueue[I] := TDog; //Probably not the way to do it...??
end;

procedure TForm1.CatButtonPressed(Sender: TObject);
var
myCat: TCat;
I: Integer;
begin
myCat := TCat.Create('123');
I := Length(myQueue);
SetLength(myQueue, I+1);
myQueue[I]: = TCat; //Probably not the way to do it...??
end;

procedure TForm1.OnProcessQueueButtonPressed(Sender: TObject);
var
MyInterface: IAnimal; //Interface variable
I: Integer;
begin
for I := Low(myQueue) to High(myQueue) do
begin
MyInterface: = myQueue[I].Create('123'); //Create instance of relevant class
MyInterface.DoSomething;
end;
end;

So, suppose You have a form with three buttons. The “dog” button, the “cat” button and the “processing queue” button. When you press the “dog” button or the “cat” button, the related classes will be added to the array to Act as a queue. Then press the “Process Queue” button, the program gradually executes the array, creates objects of related classes, and then calls the interface methods implemented in the class. Remember my sample code, how to achieve it?

The obvious way is to add the class name as a string to the string array, and then use the if statement in the OnProcessQueueButtonPressed process, for example:

procedure TForm1.OnProcessQueueButtonPressed(Sender: TObject);
var
MyInterface: IAnimal; //Interface variable
I: Integer;
begin
for I := Low(myQueue ) to High(myQueue) do
begin
if myQueue[I] ='TDog' then
MyInterface := TDog.Create('123');
if myQueue[I ] ='TCat' then
MyInterface := TCat.Create('123');
MyInterface.DoSomething;
end;
end;

I Try to avoid this, because every time I add a new class, I have to remember to add an if block for the new class.

You can use class reference performs this operation. Define the class reference type as follows:

type
TAnimalClass = class of TAnimal;

and Arrange TAnimal to support the interface:

type
IAnimal = interface
procedure DoSomething;
end;

TAnimal = class(TInterfacedObject, IAnimal)
public
constructor Create; overload;
constructor Create(param: string); overload;
procedure DoSomething; virtual; abstract;
end;

TDog = class(TAnimal)
public
procedure DoSomething; override;
end;

TCat = class(TAnimal)
public
procedure DoSomething; override;
end;

Using an array will lead to code confusion. It is better to use a list object.

var
myQueue: TList;

Now You can write the following code:

procedure TForm1.DogButtonPressed(Sender: TObject);
begin
myQueue.Add(TDog);
end;

procedure TForm1.CatButtonPressed(Sender: TObject);
begin
myQueue.Add(TCat);
end;

procedure TForm1.OnProcessQueueButtonPressed(Sender: TObject);
var
AnimalClass: TAnimalClass;
Animal: IAnimal;
begin
for AnimalClass in myQueue do
begin
Animal := AnimalClass.Create('123');
Animal.DoSomething;
end;
myQueue.Clear;
end;

You need to create and destroy an instance of myQueue in the appropriate place. I fake Assuming you already know how to do this.

When using class references, a better nuance is that you usually provide virtual constructors in the base class. This is because when you use class references to create When instantiating, you will call the constructor declared in the base class. If the constructor is not virtual, the derived class constructor code will not be executed.

Of course, using class references in this way will Make the interface meaningless.

Leave a Comment

Your email address will not be published.