启动你的时间机器,回到古代:这是Delphi,现在是2007年。
在我们的初学者手册中,我将一些编程基础(使用Delphi)写下来。在这个过程中,我发现了一个我不太理解的怪事。为了演示继承,我编写了一个基类和它的一个子类。一个函数被子类重新引入,另一个函数被重写。
unit UOverride;
interface
type
Base = class(TObject)
strict private
const
CName: String = 'Base-Class';
CMaxim: String = 'Somebody set up us the bomb.';
public
function GetName(): String; virtual;
function GetMaxim(): String; virtual;
end;
Heir = class(Base)
strict private
const
CName: String = 'Heir-Class';
CMaxim: String = 'All your Base are belong to us!';
public
function GetName(): String; reintroduce;
function GetMaxim(): String; override;
function GetBaseName(): String;
function GetBaseMaxim():String;
end;
implementation
{ Base }
function Base.GetMaxim: String;
begin
Result := CMaxim;
end;
function Base.GetName: String;
begin
Result := CName;
end;
{ Heir }
function Heir.GetMaxim: String;
begin
Result := CMaxim;
end;
function Heir.GetName: String;
begin
Result := CName;
end;
end.
当我创建一个Base对象并调用两个函数时,它按预期工作:
- GetName() => "Base-Class" - GetMaxim() => "Somebody set up us the bomb."
当我创建一个Heir实例时,同样也是这样:
- GetName() => "Heir-Class" - GetMaxim() => "All your Base are belong to us!"
现在,我将Heir实例转换为Base并再次调用两个函数。
- GetName() => "Base-Class",这没有疑问 - GetMaxim() => "All your Base are belong to us!",因为它被Heir重写。
出于好奇,我还添加了两个函数到Heir中。
function Heir.GetBaseName: String;
begin
Result := inherited GetName();
end;
function Heir.GetBaseMaxim: String;
begin
Result := inherited GetMaxim();
end;
我希望
GetBaseName()
能够给我基类 - 它确实这样做了。对于 GetBaseMaxim()
,我不确定。在我看来,有三种可能性:
- 它无法编译并抛出错误或
- 它运行并将因为被覆盖的继承函数而失败,或者
- 最有可能的是,它会给我来自Heir的
GetMaxim()
,告诉我All your Base are belong to us!。
inherited something
,你会得到直接祖先(在这种情况下是基类)的something
。我不会期望其他结果。请注意,inherited
绕过了虚拟机制。这是必须的。否则,你总是会得到最派生的something
,而如果使用inherited
,这正是你不想要的。 - Rudy Velthuisinherited
,你直接调用它。 - Rudy Velthuis