/ / Wie heißt diese "zyklische Vererbung" in Delphi? - Delphi, Erbschaft

Wie heißt diese "zyklische Vererbung" in Delphi? - Delphi, Erbschaft

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 № 1

Was 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 TcxGridDBTableViewund 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.