问题描述
我有两个包含类似数据类型的二进制文件,因此我想为这两个文件创建一个统一的查看器 (TViewer).有些方法对于这两种文件类型是通用的,有些则不是.所以我创建了一个基类TShape,以及来自它的 TCircle 和 TTriangle.
I have two binary files that contain a similar type of data so I want to create a unified viewer (TViewer) for both files.Some, methods are common for these two file types, some are not. So I created a base classTShape, and the from it TCircle and 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
并没有错,只是我必须在很多地方(接近任何地方)使用它.有更好的方法来实现这个统一的查看器吗?
Obviously there is nothing wrong in using is
except that I will have to use it in many many places (close to everywhere). There is a nicer way to achieve this unified viewer?
其实也可能是性能问题.我的文件包含大量项目(多达数十亿),因此进行如此多的is/as"测试实际上可能会对速度产生真正的影响.
Actually, it may be also a performance problem. My file has a really big number of items (up to billions) so doing so many 'is/as' tests may actually have a real impact on speed.
推荐答案
你做错了.
您需要更改代码,以便在您知道需要的类型之前不会创建容器,然后创建正确的类型:
You need to change your code so that the container is not created until you know what type it needs to be, and then create the proper type:
Procedure Main;
begin
if FileType= Circle then
Viewer.Container := TCircle.Create
else
Viewer.Container := TTriangle.Create;
Viewer.Container.Load(FileName);
Caption := IntToStr(Viewer.Container.NoOfItems); <---- it calls proper code
end;
这是一个为您使用继承和多态的工作示例:
Here's a working example of using inheritance and polymorphism for you:
program InheritancePolymorphismTest;
uses
System.SysUtils;
type
TAnimal=class
public
procedure Sit; virtual;
procedure Speak; virtual;
end;
TDog=class(TAnimal)
public
procedure Sit; override;
procedure Speak; override;
end;
TCat=class(TAnimal)
public
procedure Speak; override;
end;
TAnimalArray = array of TAnimal;
{ TCat }
procedure TCat.Speak;
begin
inherited;
WriteLn('Bah! No way cats speak when told.');
end;
{ TDog }
procedure TDog.Sit;
begin
inherited;
WriteLn('Sitting down.');
end;
procedure TDog.Speak;
begin
inherited;
Writeln('Woof! Woof!');
end;
procedure TAnimal.Sit;
begin
end;
procedure TAnimal.Speak;
begin
end;
var
Animals: TAnimalArray;
i: Integer;
Pet: TAnimal;
{ TAnimal }
const
NumAnimals = 5;
begin
SetLength(Animals, NumAnimals);
for i := 0 to High(Animals) do
begin
if Odd(i) then
Animals[i] := TDog.Create
else
Animals[i] := TCat.Create;
end;
for Pet in Animals do
begin
Pet.Speak;
Pet.Sit;
end;
Writeln('');
Readln;
end.
这篇关于继承/多态概念的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!