我的顶级类是TBaseDB
,它有一个后代TCommonDB
(并且TCommonDB
将有多个后代,例如TProdDB
和TDevDB
)。
让我们在每个类定义中创建一个称为Test1
的函数。现在,它只是做一个ShowMessage('Some literal')
来告诉我正在执行什么代码。
我直到运行时才知道类的类型。我想要通用的代码,但行为不同。
我想要的是这样的:
var
MyObj: TBaseDB;
begin
//pseudo-code...
if RadioButton1.Checked then
MyObj := TBaseDB.Create
else
MyObj := TCommonDB.create;
MyObj.Test1;
end;
我似乎无法使它正常工作,并且我想它在我的类定义中。应该如何定义
Test1
,以便:我可以将变量声明为
TBaseDB
,创建的类可以是
TBaseDB
或TCommonDB
,并且是否根据实例是
Test
还是TBaseDB
调用正确的TCommonDB
过程? 最佳答案
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TFruit = class
public
procedure ShowMessage; virtual; abstract;
end;
TApple = class(TFruit)
public
procedure ShowMessage; override;
end;
TOrange = class(TFruit)
public
procedure ShowMessage; override;
end;
{ TApple }
procedure TApple.ShowMessage;
begin
Writeln('I''m an apple!');
end;
{ TOrange }
procedure TOrange.ShowMessage;
begin
Writeln('I''m an orange!');
end;
var
fruit: TFruit;
begin
fruit := TApple.Create;
fruit.ShowMessage;
Writeln('Press Enter to continue.');
Readln;
end.
关键字
abstract
允许您在基类中根本没有任何实现。但是,您也可以在那里实现:program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TFruit = class
public
procedure ShowMessage; virtual;
end;
TApple = class(TFruit)
public
procedure ShowMessage; override;
end;
TOrange = class(TFruit)
public
procedure ShowMessage; override;
end;
{ TFruit }
procedure TFruit.ShowMessage;
begin
Writeln('I''m a fruit.');
end;
{ TApple }
procedure TApple.ShowMessage;
begin
inherited;
Writeln('I''m an apple!');
end;
{ TOrange }
procedure TOrange.ShowMessage;
begin
inherited;
Writeln('I''m an orange!');
end;
var
fruit: TFruit;
begin
fruit := TApple.Create;
fruit.ShowMessage;
Writeln('Press Enter to continue.');
Readln;
end.
练习:
在每种情况下,如果创建
TFruit
的实例会怎样?在第二种情况下,
inherited
和TApple.ShowMessage
中的TOrange.ShowMessage
是什么意思?他们是否需要处于流程的顶部?如果您省略它们会怎样?