前几天我看到了这样的密码:
type
TcxGridTableControllerAccess = class (TcxGridTableController);
TMycxGridDBTableView = class (TcxGridDBTableView)
protected
function GetViewDataClass: TcxCustomGridViewDataClass; override;
end;
TMycxGridViewData = class (TcxGridViewData)
protected
function GetFilterRowClass: TcxGridFilterRowClass; override;
end;
TMycxGridFilterRow = class (TcxGridFilterRow)
protected
procedure SetValue(Index: Integer; const Value: Variant); override;
end;
TcxGridDBTableView = class (TMycxGridDBTableView);
TMycxGridDBTableView继承自TcxGridDBTableView,继承自TMycxGridDBTableView。搜索循环继承,但只搜索Java结果。
这叫什么?
Ps:我没有完整的可构建代码。
发布于 2016-08-02 18:45:08
所显示的不是循环继承。结果是dxSample.TMycxGridDBTableView
继承了另一个单元中的TcxGridDBTableView
,很可能是cxGridDBTableView.TcxGridDBTableView
。dxSample.TcxGridDBtableView
是从dxSample.TMycxGridDBTableView
继承来的。
您的代码等效于:
type
TcxGridTableControllerAccess = class(TcxGridTableController);
{ Note: this does NOT inherit from the TcxGridDBTableView defined }
{ a little further on in the source. It inherits from the original }
{ DevEx TcxGridDBTableView. }
TMycxGridDBTableView = class(cxGridDBTableView.TcxGridDBTableView)
protected
function GetViewDataClass: TcxCustomGridViewDataClass; override;
end;
TMycxGridViewData = class(TcxGridViewData)
protected
function GetFilterRowClass: TcxGridFilterRowClass; override;
end;
TMycxGridFilterRow = class(TcxGridFilterRow)
protected
procedure SetValue(Index: Integer; const Value: Variant); override;
end;
TcxGridDBTableView = class(TMycxGridDBTableView);
所以等级是:
cxGridDBTableView.TcxGridDBTableView
|
v
dxSample.TMycxGridDBTableView
|
v
dxSample.TcxGridDBTableView
因此,dxSample.TMycxGrdiDBTableView
并不是从dxSample.TcxGridDBTableView
继承的,而是从cxGridDBTableView.TcxGridDBTableView
继承的,因此没有所谓的循环继承。整个误解来自于这样一个事实:不同单元中的两个类具有相同的名称,并且第一个声明没有完全限定它所继承的类。
现在,如果有人将单元dxSample
放在cxridDBTableView
后面的uses
子句中,那么就使用了dxSample.TCxGridDBTableView
,而不是原来的DevEx类。这就是所谓的插曲。
当人们想要修改VCL和FireMonkey的行为时,看到诸如
type
TVCLClass = class(OriginalVCLUnit.TVCLClass)
// modifications to the original TVCLClass
end;
或
type
TMyVCLClass = class(OriginalVCLUnit.TVCLClass)
//
end;
TVCLClass = class(TMyVCLCLass);
你展示的代码就是后者。
发布于 2016-08-02 18:36:25
示例代码不像您认为的那样。您可以看到TMycxGridDBTableView
被定义为TcxGridDBTableView
的后代,然后您看到TcxGridDBTableView
,它被定义为TcxGridDBTableView
的后代。
但是,您在顶部看到的TcxGridDBTableView
与稍后看到的TcxGridDBTableView
不同。第一个是指在其他单位中在其他地方声明的类。下一个情况是在这个单元中声明一个与另一个单元的类具有相同的基名的新类。
这种技术被称为interposer类。它用于引入一个新的GetViewDataClass
方法,但最终仍然以相同的类名结束。使用具有该名称的控件的窗体将使用类的新版本而不是原始版本。这是一种自定义VCL控件的方法,而无需编译和安装自定义包。
https://stackoverflow.com/questions/38727811
复制相似问题