Ich habe neulich so einen Code gesehen:
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 wurde von TcxGridDBTableView geerbt, die von TMycxGridDBTableView geerbt wurde. Es wurde nach zyklischer Vererbung, aber nur Java-Ergebnissen gesucht.
Wie heißt das?
Ps: Ich habe nicht den vollständigen Code, den ich bauen kann.
Antworten:
6 für die Antwort № 1Was du zeigst ist nicht zyklisch Erbe. Was passiert ist das dxSample.TMycxGridDBTableView
erbt von a TcxGridDBTableView
wahrscheinlich in einer anderen Einheit cxGridDBTableView.TcxGridDBTableView
. Und dxSample.TcxGridDBtableView
erbt von dxSample.TMycxGridDBTableView
.
Ihr Code entspricht:
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);
Die Hierarchie lautet also:
cxGridDBTableView.TcxGridDBTableView
|
v
dxSample.TMycxGridDBTableView
|
v
dxSample.TcxGridDBTableView
Damit dxSample.TMycxGrdiDBTableView
tut nicht geerbt von dxSample.TcxGridDBTableView
, aber von cxGridDBTableView.TcxGridDBTableView
stattdessen so Es gibt keine sogenannte zyklische Vererbung Dort. Das ganze Missverständnis rührt von der Tatsache her, dass die beiden Klassen in den verschiedenen Einheiten denselben Namen haben und die erste Deklaration die Klasse, von der sie erbt, nicht vollständig qualifiziert.
Nun, wenn jemand die Einheit setzt dxSample
nach cxridDBTableView
in seinem oder ihr uses
dann Klausel dxSample.TCxGridDBTableView
wird anstelle der ursprünglichen DevEx-Klasse verwendet. Das nennt man einlegen.
Wenn Benutzer das Verhalten der VCL und von FireMonkey ändern möchten, ist es nicht ungewöhnlich, Interposer-Klassen wie
type
TVCLClass = class(OriginalVCLUnit.TVCLClass)
// modifications to the original TVCLClass
end;
oder
type
TMyVCLClass = class(OriginalVCLUnit.TVCLClass)
//
end;
TVCLClass = class(TMyVCLCLass);
Der Code, den Sie gezeigt haben, macht das letztere.
9 für die Antwort № 2
Der Beispielcode tut nicht das, was Sie denken TMycxGridDBTableView
als Nachkomme von TcxGridDBTableView
und dann siehst du TcxGridDBTableView
, definiert als Nachkomme von TcxGridDBTableView
.
Aber die TcxGridDBTableView
Sie sehen an der Spitze nicht dasselbe TcxGridDBTableView
das sie später sehen. Die erste bezieht sich auf eine Klasse, die an anderer Stelle in einer anderen Einheit deklariert wurde. Das nächste Vorkommen deklariert a Neu Klasse in Dies Einheit, die zufällig denselben Basisnamen hat wie die Klasse der anderen Einheit.
Diese Technik ist bekannt als Interposer-Klasse. Es wird verwendet, um ein neues einzuführen GetViewDataClass
Methode, aber immer noch mit dem gleichen Klassennamen. Das Formular, das Steuerelemente mit diesem Namen verwendet, verwendet anstelle der ursprünglichen Version die neue Version der Klasse. Es ist eine Möglichkeit, ein VCL-Steuerelement anzupassen, ohne dass ein benutzerdefiniertes Paket kompiliert und installiert werden muss.