【发布时间】:2014-04-28 18:58:46
【问题描述】:
我有两个包含相似类型数据的二进制文件,因此我想为这两个文件创建一个统一查看器 (TViewer)。 有些方法对于这两种文件类型是通用的,有些则不是。所以我创建了一个基类 TShape,以及由此而来的 TCircle 和 TTriangle。
伪代码:
TShape = class(TObject)
function NoOfItems: integer; virtual; abstract;
end;
TCircle = class(TShape)
function NoOfItems: integer; override; <---- The real implementation
end;
TTriangle = class(TShape)
function NoOfItems: integer; override; <---- The real implementation
end;
TViewer = class(TStringGrid)
Container: TShape;
end;
我是这样使用它的:
Procedure Main;
begin
if FileType= Circle
then (Viewer.Container as TCircle).Load(FileName)
else (Viewer.Container as TTriangle).Load(FileName);
Caption:= Viewer.Container.NoOfItems; <---- it calls TShape which is abstract
end;
当我这样做时,它会起作用:
if Viewer.Container is TTriangle
then Caption:= (Viewer.Container as TTriangle).NoOfItems
else ...
但我想直接这样做:
Caption:= Viewer.Container.NoOfItems;
显然,使用is 并没有什么问题,只是我必须在很多地方(几乎无处不在)使用它。有更好的方法来实现这个统一的查看器吗?
更新:
其实也可能是性能问题。我的文件包含非常多的项目(多达数十亿),因此执行如此多的“原样”测试实际上可能会对速度产生真正的影响。
【问题讨论】:
-
当然,你可以使用
IntVar := Viewer.Container.NoOfItems;——这是典型的多态用法 -
您根本不必对它进行类型转换(并且不要使用示例中的代码),这意味着这很可能不是您的真实代码。 (实际上,这个不可能是你真正的代码,因为你已经将
NoOfItems声明为一个返回integer的函数,但是你直接将它分配给Caption。)发布真正的代码如果你需要帮助。 -
@MBo - 它将调用 TShape 的方法。什么都不做(抽象的)。
-
@KenWhite - 是的。这不是真正的代码。真正的代码非常大,可以在这里发布。我将尝试制作一个小的 COMPILABLE 演示。无论如何,Viewer.Container.NoOfItems 调用了 TShape 的方法,它什么也不返回!
-
好的。我在 TShape 中添加了 Abstract。现在显然 Viewer.Container.NoOfItems 失败了。