我有一个界面的TList
IImage = interface
// another methods...
procedure Draw;
end;
在画布中绘制不同的东西。
和父类
TCustomImage = class(TInterfacedObject, IImage)
procedure Draw; virtual; abstract;
end;
和几个孩子班
TSomeShape = class(TCustomImage, IImage)
procedure Draw(aCanvas:TCanvas); reintroduce; overload;
end;
TSomeAnotherShape = class(TCustomImage, IImage)
procedure Draw(aCanvas:TCanvas); reintroduce; overload;
end;
我想编码如下:
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
我想将list.Items[I].draw()
与正确的类(TSomeShape
或TSomeAnotherShape
)一起使用。但现在,我发现这个IImage
界面是不可能的。我在IImage中有一个方法Draw(Canvas:TCanvas)
,但认为在类中重新引入方法是可以接受的。
谢谢,我会处理我的代码。 :)
答案 0 :(得分:3)
问题是您的界面定义不正确。您的具体类使用此签名实现方法:
procedure Draw(Canvas: TCanvas);
但您的界面使用此签名定义了一个方法:
procedure Draw;
您确实需要您的界面和具体实现相匹配。你会想要这样的代码:
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;
现在一切都匹配,你的代码应该编译得很好,甚至可以做你想要的。
顺便说一句,您的try
位置错误。您必须将放在之后才能实例化对象。写
obj := TSomeClass.Create;
try
// use obj
finally
obj.Free;
end;
正如您在代码中所拥有的那样,构造函数中的异常将导致finally块运行并尝试在未初始化的引用上调用free。