Property是一個很有意思的語法特性,它使得方法具有了字段的調用特征,並賦予字段執行動作的能力。
如果你使用過C++ Builder來寫基於VCL的程序,我想很多人都會注意到這樣一點,比如:
edt.Text = "test"; 這個時候edt文本框的內容會隨之改變,但是“理論”上Text應該只是改變了Text所在的內存數據而已,為什么會導致窗口更新界面着一些列動作?
這就是因為Property這一特性,Property是Borland為C++擴展的語法特性,目的在於使C++ Builder能夠方便的使用VCL庫,畢竟VCL是使用Object Pascal寫的。
有些扯遠了,言歸正傳,這里還是總結一下在Delphi中如何使用Poperty這一語法特性。
如果學習過C#的朋友應該會很容易理解,因為C#的屬性就是學習自Delphi,畢竟C#和Delphi是同一個設計者。
定義一個屬性Property的基本格式如下:
property 屬性名 : 屬性值類型 read 屬性讀函數/屬性值變量 write 屬性寫函數/屬性值變量
這里簡單解釋一下:
1。Property是屬性定義關鍵字。
2。屬性的特征類似於字段,所以屬性名就像字段名,屬性值類型就像字段的值類型
3。屬性讀函數,是屬性被“讀取”時所執行的操作,這樣在執行“取值”操作時,具備了執行其他動作的可能。
另外,屬性值變量,可以是Property所在類能夠訪問的任何變量,如果使用了屬性值變量,則相當於屬性值直接從值變量中獲取,這和直接賦值是沒有什么差別的
4。屬性寫函數,是屬性被“寫入”時所執行的操作,這樣在執行屬性“賦值”操作時,具備了執行其他動作的可能。比如:寫入edt的Text屬性時,窗口會同時執行界面更新操作。
另外,屬性值變量和3中所述類似,如果使用了,就相當於將傳來的屬性值直接賦值到對應的屬性值變量
這里的函數是真正的函數,不像C#中那樣的getter和setter,所以會有些難以理解。
5。屬性讀函數的函數聲明:
function 讀函數名: 屬性值類型;
其中讀函數名可以自定義,只要和屬性聲明中一樣即可,該函數的返回值就是讀屬性操作時實際獲取的值。
6。屬性寫函數聲明(其實是一個子函數):
procedure 寫函數名(value : 屬性值類型)
其中寫函數名可以自定義,只要和屬性聲明中一樣即可,該函數參數value,就是對屬性賦值時傳遞過來的實際值。
7。讀函數和寫函數必須設置一個,如果只設置讀函數,而沒有設置寫函數(同時去掉write關鍵字),這樣的屬性就是只讀屬性,同理也可以設置只寫屬性
8。為了保證屬性公開性的同時掩蓋讀寫函數的可見性,可以將讀寫函數設置為私有,而將屬性設置為共有,這樣可以避免將讀寫函數本身暴露給調用者,否則就不太拉風了。
舉例:
TxKernelSearchThread = class(TThread)
private
keyword_list: TStringList;
procedure SetKeyword(value: UnicodeString);
public
property Kerword:UnicodeString write SetKeyword;
。。。
end;
procedure TxKernelSearchThread.SetKeyword(value: UnicodeString);
begin
if value = '' then Exit;
ExtractStrings([' '],[' '],PWideChar(value),Self.keyword_list);
end;
上面是一個只寫屬性的例子。
屬性的一個很重要的應用就是VCL中的控件屬性,以及事件屬性等,這也就解釋了為什么向文本框的Text屬性賦值,會更新界面操作,這正是因為屬性將字段和函數的特征結合了起來。