Delphi 物件模型中,每個類別實例都攜帶運行時類型資訊,透過 ClassType、ClassParent 與 TClass 可在運行時動態檢查與遍歷完整繼承體系。本文通過四個按鈕範例逐步演示從單層查詢到完整鏈路遍歷的技巧。
type
TForm1 = class(TForm)
Button1, Button2, Button3, Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Self.ClassName); { TForm1 }
ShowMessage(Self.ClassParent.ClassName); { TForm }
ShowMessage(Self.ClassParent.ClassParent.ClassName); { TCustomForm }
end;
適用於已知固定層級的快速查詢,但寫死層數不靈活。
procedure TForm1.Button2Click(Sender: TObject);
var
MyClass: TClass; { TClass = class of TObject }
begin
ShowMessage(Self.ClassType.ClassName); { TForm1 }
MyClass := Self.ClassType;
ShowMessage(MyClass.ClassName); { TForm1 }
end;
ClassType 返回實例的確切類別參考(TClass)。TClass 本質是指向類別元數據的指標,可賦值、傳參、比較。procedure TForm1.Button3Click(Sender: TObject);
var
MyClass: TClass;
begin
MyClass := Self.ClassType;
ShowMessage(MyClass.ClassName); { TForm1 }
MyClass := MyClass.ClassParent;
ShowMessage(MyClass.ClassName); { TForm }
MyClass := MyClass.ClassParent;
ShowMessage(MyClass.ClassName); { TCustomForm }
end;
ClassParent 同樣返回 TClass,可直接賦值給 TClass 變量鏈式遍歷。
procedure TForm1.Button4Click(Sender: TObject);
var
MyClass: TClass;
begin
MyClass := Self.ClassType;
while MyClass <> nil do
begin
ShowMessage(MyClass.ClassName);
MyClass := MyClass.ClassParent;
end;
end;
TForm1 TForm TCustomForm TScrollingWinControl TWinControl TControl TComponent TPersistent TObject
| 成員 | 類型/返回 | 說明 |
|---|---|---|
ClassName | string | 類別名稱(如 'TButton') |
ClassType | TClass | 實例的確切類別參考 |
ClassParent | TClass | 父類別參考,頂層為 nil |
InheritsFrom(AClass: TClass) | Boolean | 判斷是否繼承自指定類別(含自身) |
ClassInfo | PTypeInfo | RTTI 型別資訊指標(需 {$M+}) |
is/asif Obj.ClassType.InheritsFrom(TButton) then
TButton(Obj).Click; // 安全轉型後呼叫
var
FactoryMap: TDictionary;
function CreateComponent(AClass: TClass; Owner: TComponent): TComponent;
begin
if FactoryMap.ContainsKey(AClass) then
Result := FactoryMap[AClass].Create(Owner)
else
Result := nil;
end;
function GetInheritancePath(Obj: TObject): string;
var
Cls: TClass;
Parts: TArray;
begin
Cls := Obj.ClassType;
while Cls <> nil do
begin
Parts := Parts + [Cls.ClassName];
Cls := Cls.ClassParent;
end;
Result := string.Join(' → ', Parts);
end;
ClassParent 在 TObject 為 nil,迴圈條件必須檢查 MyClass <> nil。interface)不在類別繼承鏈中,需用 GetInterface/Supports 查詢。ClassType。熟練運用 ClassType/ClassParent/TClass,能構建動態工廠、診斷工具、序列化框架等高級基礎設施,是 Delphi 元編程的必備技能。