Ian*_*oyd 23 delphi inheritance
我正在覆盖一个虚方法,我想调用继承.但我不想叫直接祖先,我想调用一个之前.
TObject
TDatabaseObject
TADODatabaseObject <---call this guy
TCustomer <---skip this guy
TVIP <---from this guy
Run Code Online (Sandbox Code Playgroud)
我尝试将我self作为祖先,然后调用该方法,但它导致递归堆栈溢出:
procedure TVip.SetProperties(doc: IXMLDOMDocument);
begin
TADODatabaseObject(Self).SetProperties(doc); //skip over TCustomer ancestor
...
end;
Run Code Online (Sandbox Code Playgroud)
我尝试添加inherited关键字,但不编译:
procedure TVip.SetProperties(doc: IXMLDOMDocument);
begin
inherited TADODatabaseObject(Self).SetProperties(doc); //skip over TCustomer ancestor
...
end;
Run Code Online (Sandbox Code Playgroud)
可能?
klu*_*udg 28
您可以使用获取虚拟方法的静态地址来执行此操作:
type
TBase = class
procedure Foo; virtual;
end;
TAnsestor = class(TBase)
procedure Foo; override;
end;
TChild = class(TAnsestor)
procedure Foo; override;
procedure BaseFoo;
end;
procedure TBase.Foo;
begin
ShowMessage('TBase');
end;
procedure TAnsestor.Foo;
begin
ShowMessage('TAnsestor');
end;
procedure TChild.Foo;
begin
ShowMessage('TChild');
end;
type
TFoo = procedure of object;
procedure TChild.BaseFoo;
var
Proc: TFoo;
begin
TMethod(Proc).Code := @TBase.Foo; // Static address
TMethod(Proc).Data := Self;
Proc();
end;
procedure TForm4.Button1Click(Sender: TObject);
var
Obj: TChild;
Proc: TFoo;
begin
Obj:= TChild.Create;
Obj.BaseFoo;
// or else
TMethod(Proc).Code := @TBase.Foo; // Static address
TMethod(Proc).Data := Obj;
Proc();
Obj.Free;
end;
Run Code Online (Sandbox Code Playgroud)
我记得几年前我必须做一些这样的事情来解决VCL层次结构的一些设计限制.
所以它似乎是这样的:
type
TGrandParent = class(TObject)
public
procedure Show;virtual;
end;
TParent = class(TGrandParent)
public
procedure Show;override;
end;
THackParent = class(TGrandParent)
private
procedure CallInheritedShow;
end;
TMyObject = class(TParent)
public
procedure Show;override;
end;
{ TGrandParent }
procedure TGrandParent.Show;
begin
MessageDlg('I''m the grandparent', mtInformation, [mbOk], 0);
end;
{ TParent }
procedure TParent.Show;
begin
inherited;
MessageDlg('I''m the parent', mtInformation, [mbOk], 0);
end;
{ THackParent }
procedure THackParent.CallInheritedShow;
begin
inherited Show;
end;
{ TVIP }
procedure TMyObject.Show;
begin
THackParent(Self).CallInheritedShow;
end;
procedure TForm6.Button6Click(Sender: TObject);
var
VIP: TMyObject;
begin
VIP:=TMyObject.Create;
try
VIP.Show;
finally
VIP.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
不是晚餐优雅,但仍然是一个解决方案:)