Reputation: 372
I have a TList of an interface
IImage = interface
// another methods...
procedure Draw;
end;
that draw different stuff in a Canvas.
and a parent class
TCustomImage = class(TInterfacedObject, IImage)
procedure Draw; virtual; abstract;
end;
and a couple of child classes
TSomeShape = class(TCustomImage, IImage)
procedure Draw(aCanvas:TCanvas); reintroduce; overload;
end;
TSomeAnotherShape = class(TCustomImage, IImage)
procedure Draw(aCanvas:TCanvas); reintroduce; overload;
end;
I would like to code as below:
var
list : TList<IImage>;
shape : IImage;
begin
try
list := TList<IImage>.Create;
list.Add(TSomeShape.Create(atSomePosition));
list.Add(TSomeAnotherShape.Create(atSomePosition));
// or better :)
for shape in list do
shape.Draw(Canvas); // TSomeShape and TSomeAnotherShape respectively.
finally
FreeAndNil(list);
end;
end;
UPD
I want to use the list.Items[I].draw()
with the correct classes (TSomeShape
or TSomeAnotherShape
). But now, I see that it is impossible with this IImage
interface. I had a method Draw(Canvas:TCanvas)
in the IImage but thought that it is acceptably to reintroduce method in classes.
Thanks, I`ll work on my code. :)
Upvotes: 0
Views: 747
Reputation: 612934
The problem is that your interface is defined incorrectly. Your concrete classes implement methods with this signature:
procedure Draw(Canvas: TCanvas);
But your interface defines a method with this signature:
procedure Draw;
You do need your interface and the concrete implementations to match. You'll want code like this:
type
IImage = interface
procedure Draw(Canvas: TCanvas);
end;
TCustomImage = class(TInterfacedObject, IImage)
procedure Draw(Canvas: TCanvas); virtual; abstract;
end;
TSomeShape = class(TCustomImage)
procedure Draw(Canvas: TCanvas); override;
end;
TSomeOtherShape = class(TCustomImage)
procedure Draw(Canvas: TCanvas); override;
end;
Now everything matches and your code should compile fine, and maybe even do what you want it to.
As an aside, your try
is in the wrong place. You must place it after you instantiate the object. Write
obj := TSomeClass.Create;
try
// use obj
finally
obj.Free;
end;
As you have it in your code, an exception in the constructor will lead to the finally block running and attempting to call free on an uninitialized reference.
Upvotes: 4