Reputation: 25
I have a main class and several inherited classes that implement a method with the same name, like this:
MainClass = class(TImage)
//main class methods...
end;
MyClass1 = class(MainClass)
procedure DoSomething;
end;
MyClass2 = class(MainClass)
procedure DoSomething;
end;
MyClass3 = class(MainClass)
procedure DoSomething;
end;
I also have a TList containing pointers to object instances (of several classes).
If I want to call the right DoSomething
procedure for each class, do I use the following?
if TList[i] is MyClass1 then
MyClass1(TList[i]).DoSomething
else if TList[i] is MyClass2 then
MyClass2(TList[i]).DoSomething
else if TList[i] is MyClass3 then
MyClass3(TList[i]).DoSomething
Is there some casting method that allows me to do this in a few lines of code?
Upvotes: 2
Views: 2861
Reputation: 57525
Yes, virtual polymorphism :)
MainClass = class(TImage)
procedure DoSomething; virtual;
end;
MyClass1 = class(MainClass)
procedure DoSomething; override;
end;
MyClass2 = class(MainClass)
procedure DoSomething; override;
end;
MyClass3 = class(MainClass)
procedure DoSomething; override;
end;
And then just:
if TList[i] is MainClass then
MainClass(TList[i]).DoSomething
If you don't want to do an empty MainClass.DoSomething
procedure, you can also mark it virtual; abstract;
.
Upvotes: 10
Reputation: 326
The virtual inheritance answer is the best for the situation you described where the classes descend from a common base class, but if you have a situation where there is not a common base class between your classes and you need this behavior, you can use interfaces instead to achieve the same result:
IMainInterface = interface
['{0E0624C7-85F5-40AF-ADAC-73B7D79C264E}']
procedure DoSomething;
end;
MyClass = class(TInterfacedObject, IMainInterface)
procedure DoSomething;
destructor Destroy; override;
end;
MyClass2 = class(TInterfacedObject, IMainInterface)
procedure DoSomething;
end;
MyClass3 = class(TInterfacedObject, IMainInterface)
procedure DoSomething;
end;
and then using it would look something like this:
var
i: integer;
list: TInterfaceList;
main: IMainInterface;
begin
list := TInterfaceList.Create;
list.Add(MyClass.create);
list.Add(MyClass2.Create);
list.Add(MyClass3.Create);
for i := 0 to 2 do
if Supports(list[i], IMainInterface, main) then
main.DoSomething;
list.Free;
Upvotes: 4