本文為原創,如需轉載,請注明作者和出處,謝謝!
在面向對象語言中,用兩種方法建立類的實例:靜態建立和動態建立。靜態建立就是在程序中顯式地建立類的實例,如c1 =
TClass1.Create()。而動態建立是在只知道類名的前題下建立類的實例。動態建立在實現上要比靜態建立更靈活,因為動態建立無需引用被建立
類,并且更容易實現如多態等面向對象特性。
一、 動態建立類的實例
在delphi中動態建立類的實例可分為4步。
1. 聲明一個從TPersistent繼承的類。因為在注冊類時要求必須從TPersistent繼承。
2. 注冊類。可以使用RegisterClass等過程進行注冊。
3. 驗證類是否被注冊(可選)。如果確定要建立的類已經注冊了,可以省略此步。
4. 得到并建立類。可使用FindClass(classname)得到要建立的類,然后使用Create方法建立類的實例。
下面給出一個動態建立類實例的簡單實現。
第一步的代碼
TClass1 = class(TPersistent)
public
function GetValue(): String;
end;
function TClass1.GetValue(): string;
begin
result := 'hello world';
end;
第二步的代碼
Initialization //可將這兩行放在end.的前面
RegisterClass(TClass1);
第三步和第四步的代碼
procedure TForm1.Button1Click(Sender: TObject);
var
class1: TClass1;
begin
if GetClass('TClass1')<>nil then
begin
class1 := FindClass('TClass1').Create as TClass1;
showmessage(class1.GetValue);
end;
end;
在delphi
中不僅可以根據類名動態建立類的實例,而且在注冊時可以給類起一個別名,在建立類的實例時即可以使用類名,也可以使用別名。如上述代碼中
RegisterClass(TClass1);可改為RegisterClassAlias(TClass1,
‘class1’);。而FindClass(‘TClass1’)也可改為FindClass(‘class1’)。另外,如果注冊的類比較多,也可使
用RegisterClasses一次注冊多個類。RegisterClasses的定義如下。
procedure RegisterClasses(AClasses: array of TPersistentClass);
首先聲明一個TpersistentClass類型的數組,然后將要注冊的類按順序賦到這個數組中,最后調用RegisterClasses即可。
二、通過動態建立實現多態
多
態在程序設計中是非常重要的概念之一。它主要是通過繼承來實現的。簡單地說,就是n個類從一個類繼承或實現一個接口,這n個類繼承父類的所有
virtual方法或實現父接口的所有方法,并做出不同的實現。這n個類的實現都不一樣,而它們的調用確是一樣的,即對于調用來說是透明的。
如果使用靜態建立類實例的方法實現多態,當類很多時需要進行大量的判斷。而使用動態建立類實例的方法只要將子類的類名或別名當做參數傳入即可。下面舉一個例子如何在delphi中利用動態建立類實例的方法實現多態。
//定義父類
TClassParent = class(TPersistent)
public
//這是一個抽象虛函數,相當于c++的純虛函數
function Greet(name: string): string; virtual; abstract;
end;
//定義兩個子類
TEnglish = class(TClassParent)
function Greet(name: string): string; override;
end;
TChinese = class(TClassParent)
function Greet(name: string): string; override;
end;
//實現兩個子類的Greet函數
{ TClassEnglish }
function TEnglish.Greet(name: string): string;
begin
result := 'hello ' + name; //返回英文的問候
end;
{ TClassChinese }
function TChinese.Greet(name: string): string;
begin
result := '您好 ' + name; //返回中文的問候
end;
//注冊兩個子類
initialization
RegisterClassAlias(TEnglish, 'eng');
RegisterClassAlias(TChinese, 'chn');
//根據用戶的選擇建立類的實例
procedure TForm1.Button2Click(Sender: TObject);
var
parent: TClassParent;
begin
if GetClass(combobox1.Items[combobox1.itemindex])<>nil then
begin
//此處FindClass的參數可以是類名,也可以是別名
//本例中將類名放入了combobox中
parent := FindClass(combobox1.Items[combobox1.itemindex]).Create as TClassParent;
showmessage(parent.Greet('bill gates'));
end;
end;
程序界面
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining