我正在开发一个源自商业组件套件的组件,并且遇到了一个我以前从未考虑过的挑战。请考虑以下代码段:
TMyClass = class
protected
procedure SomeMethod; virtual;
end;
TMyClass1 = class(TMyClass)
protected
procedure SomeMethod; override;
end;
TMyMode = (mmOne, mmTwo);
TMyClass2 = class(TMyClass1)
private
FMode: TMyMode;
protected
procedure SomeMethod; override;
public
property Mode: TMyMode read FMode write FMode;
end;
...
procedure TMyClass2.SomeMethod;
begin
if FMode = mmOne then inherited SomeMethod
else inherited TMyClass.SomeMethod;
end;
因此,如果Mode = mmOne,那么我继承正常,但如果它是mmTwo,我仍然想继承祖先祖先的代码,但不是祖先中引入的代码。我已经尝试了上述内容,没有成功,因为我以前从未遇到过这种情况,所以我认为这是不可能的。任何人?
答案 0 :(得分:6)
您可以使用课程助手:
type
TA = class
public
procedure X; virtual;
end;
TB = class(TA)
public
procedure X; override;
end;
TA_Helper = class helper for TA
procedure A_X;
end;
TC = class(TB)
public
procedure X; override;
end;
procedure TA.X;
begin
// ...
end;
procedure TB.X;
begin
// ...
end;
procedure TA_Helper.A_X;
begin
inherited X; // TA.X
end;
procedure TC.X;
begin
A_X;
inherited X; // TB.X
end;
我认为D2006中存在类助手,但如果他们不这样做,你也可以使用hack来达到同样的效果:
// ...
TA_Helper = class(TA)
procedure A_X;
end;
// ...
procedure TC.X;
begin
TA_Helper(Self).A_X;
inherited X; // TB.X
end;
答案 1 :(得分:4)
此任务的另一个解决方案是没有类助手或其他方法(如在@hvd回答中)。您可以获取基类方法代码地址并使用self
数据指针调用它:
更新后的代码,没有rtti
unit Unit4;
interface
type
TA = class(TObject)
protected
procedure Test(); virtual;
end;
TB = class(TA)
protected
procedure Test(); override;
end;
TC = class(TB)
public
procedure Test(); override;
end;
implementation
procedure TA.Test;
begin
writeln('TA.Test()');
end;
procedure TB.Test;
begin
writeln('TB.Test');
end;
procedure TC.Test;
var TATest : procedure of object;
begin
writeln('TC.Test();');
writeln('call inherited TB: ');
inherited Test();
writeln('call inherited TA:');
TMethod(TATest).Data := self;
TMethod(TATest).Code := @TA.Test;
TATest();
end;
end.