Delphi 覆盖的意外行为
Delphi unexpected behavior of override
打开你的时光机,穿越到古代:现在是Delphi,现在是2007年。
对于我们的初学者手册,我写下了一些基本的编程知识(Delphi)。这样做我发现了一个怪癖,我不太明白。为了演示继承,我写了一个基 class 和它的继承人。一个功能被重新引入,另一个被 Heir 覆盖。
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 对象并调用 too 函数时,它按预期工作:
GetName()
=> Base-Class 和
GetMaxim()
=>有人给我们安了炸弹。
继承人的实例相同:
GetName()
=> 继承人-Class 和
GetMaxim()
=>你所有的基地都是我们的!
现在我将我的 Heir 实例转换为 Base 并再次调用这两个函数。
GetName()
=> Base-Class 没有留下任何问题
GetMaxim()
=>你所有的基地都属于我们! 正如预期的那样,因为它被继承人覆盖了。
出于好奇,我又给 Heir 添加了两个函数。
function Heir.GetBaseName: String;
begin
Result := inherited GetName();
end;
function Heir.GetBaseMaxim: String;
begin
Result := inherited GetMaxim();
end;
我希望 GetBaseName()
给我 Base-Class - 所以它发生了。 GetBaseMaxim()
我不确定。在我看来,三件事是可能的
- 它不编译并抛出错误或者
- 它运行并会失败并出现异常(因为继承的函数被覆盖或
- 最期待它给了我
GetMaxim()
继承人告诉我 你所有的基地都属于我们!.
都没有发生!我从我的基地 class 有人给我们安装了炸弹。?!为什么?我认为这个功能被 Heir 覆盖了!这没什么大不了的,但我不太理解这种行为,因为它没有像我预期的那样工作。有什么解释吗?
Inherited
向祖先函数提供非虚拟分派,而这正是您所观察到的。大多数情况下,它在后代 class 中使用的函数与被调用的继承函数同名,但正如您所演示的那样,不需要自定义。您可以从后代 class.
的任何位置非虚拟地调用任何继承的方法
这没什么特别的。使用 inherited
,您请求执行基础 class。
If inherited is followed by the name of a member, it represents a
normal method call or reference to a property or field, except that
the search for the referenced member begins with the immediate
ancestor of the enclosing method's class
打开你的时光机,穿越到古代:现在是Delphi,现在是2007年。
对于我们的初学者手册,我写下了一些基本的编程知识(Delphi)。这样做我发现了一个怪癖,我不太明白。为了演示继承,我写了一个基 class 和它的继承人。一个功能被重新引入,另一个被 Heir 覆盖。
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 对象并调用 too 函数时,它按预期工作:
GetName()
=> Base-Class 和GetMaxim()
=>有人给我们安了炸弹。
继承人的实例相同:
GetName()
=> 继承人-Class 和GetMaxim()
=>你所有的基地都是我们的!
现在我将我的 Heir 实例转换为 Base 并再次调用这两个函数。
GetName()
=> Base-Class 没有留下任何问题GetMaxim()
=>你所有的基地都属于我们! 正如预期的那样,因为它被继承人覆盖了。
出于好奇,我又给 Heir 添加了两个函数。
function Heir.GetBaseName: String;
begin
Result := inherited GetName();
end;
function Heir.GetBaseMaxim: String;
begin
Result := inherited GetMaxim();
end;
我希望 GetBaseName()
给我 Base-Class - 所以它发生了。 GetBaseMaxim()
我不确定。在我看来,三件事是可能的
- 它不编译并抛出错误或者
- 它运行并会失败并出现异常(因为继承的函数被覆盖或
- 最期待它给了我
GetMaxim()
继承人告诉我 你所有的基地都属于我们!.
都没有发生!我从我的基地 class 有人给我们安装了炸弹。?!为什么?我认为这个功能被 Heir 覆盖了!这没什么大不了的,但我不太理解这种行为,因为它没有像我预期的那样工作。有什么解释吗?
Inherited
向祖先函数提供非虚拟分派,而这正是您所观察到的。大多数情况下,它在后代 class 中使用的函数与被调用的继承函数同名,但正如您所演示的那样,不需要自定义。您可以从后代 class.
这没什么特别的。使用 inherited
,您请求执行基础 class。
If inherited is followed by the name of a member, it represents a normal method call or reference to a property or field, except that the search for the referenced member begins with the immediate ancestor of the enclosing method's class