先摘一段原版的說明:
A class-reference type, sometimes called a metaclass, is denoted by a construction of the form
class of type
where type is any class type. The identifier type itself denotes a value whose type is class of type. If type1 is an ancestor of type2, then class of type2 is assignment-compatible with class of type1. Thus
type TClass = class of TObject;
var AnyObj: TClass;
declares a variable called AnyObj that can hold a reference to any class. (The definition of a class-reference type cannot occur directly in a variable declaration or parameter list.) You can assign the value nil to a variable of any class-reference type.
To see how class-reference types are used, look at the declaration of the constructor for TCollection (in the Classes unit):
type TCollectionItemClass = class of TCollectionItem;
...
constructor Create(ItemClass: TCollectionItemClass);
This declaration says that to create a TCollection instance object, you must pass to the constructor the name of a class descending from TCollectionItem.
Class-reference types are useful when you want to invoke a class method or virtual constructor on a class or object whose actual type is unknown at compile time.
光看幫助你大概搞不清楚這個有什麼用。我舉一個例子,一般mainform都有很多菜單按鈕,用來打開不同的窗口,通常做法要在uses部分添加所有要引用的單元,十分麻煩,用上面的技術就可以避免引用。假設所有的業務窗口都從TAppBasicForm繼承,你可以聲明這樣的類型:
TTAppBasicFormClass = class of TTAppBasicForm;
然後在每個業務窗口代碼結尾處加上:
initialization
RegisterClass(TBusMemberNewForm); //TBusMemberNewForm從TAppBasicForm繼承
finalization
UnRegisterClass(TBusMemberNewForm);
最後在Mainform用下面的函數:
procedure TTMainForm.ShowForm(sFormClass: string);
var
AppFormClass: TTAppBasicFormClass;
begin
try
AppFormClass := TTAppBasicFormClass(FindClass(sFormClass));
with AppFormClass.Create(self) do begin
Show;
end;
except
ShowMessage('Class ‘+sFormClass+' not exist or not register!');
end;
end;
這個函數的參數就是要打開的窗口類名
更進一步,因爲項目中Menu的hint屬性不會用到,可以用來存儲要打開的類名,如下:
procedure TTMainForm.MainFormMenuClick(Sender: TObject);
var
sFormName: string;
begin
with sender as TMenuItem do begin
sFormName := Trim(Hint);
if sFormName<>'' then ShowForm(sFormName);
end;
end;
procedure TTMainFaceForm.SetMenuAction;
var
i: integer;
begin
for i:=0 to ComponentCount-1 do begin
if Components[i] is TMenuItem then begin
with Components[i] as TMenuItem do
if Trim(Hint)<>'' then OnClick := MainFormMenuClick;
end;
end;
end;
這樣的話每增加一個菜單,只要指定菜單的hint屬性就自動實現打開對應業務的功能,避免引用單元,也不用寫菜單的onclick代碼,非常簡潔。當然這個還用到了RegisterClass和FindClass的技術,去看幫助就明白了。