對象的方法能定義成靜態(static)、虛擬(virtual)、動態(dynamic)或消息處理(message)。請看下面
的例子:
TFoo = class
procedure IAmAStatic;
procedure IAmAVirtual; virtual;
procedure IAmADynamic; dynamic;
procedure IAmAMessage(var M:TMessage); message wm_SomeMessage;
end;
1. 靜態方法
IAmAStatic 是一個靜態方法,靜態方法是方法的缺省類型,對它就像對通常的過程和函數那樣調
用。編譯器知道這些方法的地址,所以調用一個靜態方法時它能把運行信息靜態地鏈接進可執行文件。
靜態方法執行的速度最快,但它們卻不能被覆蓋來支持多態性。
2. 虛擬方法
IAmAVirtual 是一個虛擬方法。虛擬方法和靜態方法的調用方式相同。由於虛擬方法能被覆蓋,在
代碼中調用一個指定的虛擬方法時編譯器並不知道它的地址。因此,編譯器通過建立虛擬方法表(VMT)
來查找在運行時的函數地址。所有的虛擬方法在運行時通過VMT來調度,一個對象的VMT表中
除了自己定義的虛擬方法外,還有它的祖先的所有的虛擬方法,因此虛擬方法比動態方法用的內存要
多,但它執行得比較快。
3. 動態方法
IAmADynamic 是一個動態方法,動態方法跟虛擬方法基本相似,只是它們的調度系統不同。編譯
器為每一個動態方法指定一個獨一無二的數字,用這個數字和動態方法的地址構造一個動態方法表
(DMT)。不像VMT表,在DMT表中僅有它聲明的動態方法,並且這個方法需要祖先的DMT表來訪問
它其余的動態方法。正因為這樣,動態方法比虛擬方法用的內存要少,但執行起來較慢,因為有可能
要到祖先對象的DMT中查找動態方法。
4. 消息處理方法
IAmAMessage 是一個消息處理方法,在關鍵字message后面的值指明了這個方法要響應的消息。
用消息處理方法來響應Windows的消息,這樣就不用直接來調用它。
5. 方法的覆蓋
在Object Pascal覆蓋一個方法用來實現OOP的多態性概念。通過覆蓋使一方法在不同的派生類間
表現出不同的行為。Object Pascal中能被覆蓋的方法是在聲明時被標識為virtual或dynamic的方法。為
了覆蓋一個方法,在派生類的聲明中用override代替virtual或dynamic。例如,能用下面的代碼覆蓋
IAmAVirtual和IAmADynamic方法:
TFooChild = class(TFoo)
procedure IAmAVirtual; override;
procedure IAmADynamic; override;
procedure IAmAMessage(var M:TMessage); message wm_SomeMessage;
end;
用了override關鍵字后,編譯器就會用新的方法替換VMT中原先的方法。如果用virtual或dynamic替換
override重新聲明IAmAVirtual和IAmADynamic,將是建立新的方法而不是對祖先的方法進行覆蓋。同樣,
在派生類中如果企圖對一個靜態方法進行覆蓋,在新對象中的方法完全替換在祖先類中的同名方法。
6. 方法的重載
就像普通的過程和函數,方法也支持重載,使得一個類中有許多同名的方法帶着不同的參數表,
能重載的方法必須用overload指示符標識出來,可以不對第一個方法用overload。下面的代碼演示了一
個類中有三個重載的方法:
type
TSomeClass = class
procedure AMethod(I:Integer); overload;
procedure AMethod(I:String); overload;
procedure AMethod(Iouble); overload;
end;
7. 重新引入方法名稱
有時候,需要在派生類中增加一個方法,而這個方法的名稱與祖先類中的某個方法名稱相同。在
這種情況下,沒必要覆蓋這個方法,只要在派生類中重新聲明這個方法。但在編譯時,編譯器就會發
出一個警告,告訴你派生類的方法將隱藏祖先類的同名方法。要解決這個問題,可以在派生類中使用
reintroduce指示符,下面的代碼演示了reintroduce指示符的正確用法:
type
TSomeBase = class
procedure Cooper;
end;
TSomeClass = class(TSomeBase)
procedure Cooper; reintroduce;
end;
8. Self
在所有對象的方法中都有一個隱含變量稱為Self,Self是用來調用方法的指向類實例的指針。Self
由編譯器作為一個隱含參數傳遞給方法。
virtual, dynamic: 虛擬方法和動態方法, 在語義上是等價的, 只是前者是時間最優,后者是空間
abstract 抽象方法是那些在類中聲明但未實現的虛擬方法或動態方法。
抽象方法的實現推延到后裔類中。
聲明抽象方法必需在指示字virtual或dynamic之后使用abstract。
例如: procedure DoSomething; virtual; abstract;
不能調用沒有實現或沒有定義聲明的抽象方法。
override 重載,實現多態。實現或覆蓋virtual, dynamic, abstract的聲明
overload 再定義一個名稱相同但參數不同的函數. (調用時自動根據參數選擇) 跟class object 沒有關系
stdcall 使用標准的win32參數傳遞技術. 其他如register,cdecl,pascal
message 消息處理
(reintroduce表示是重新聲明的方法;用於方法的名稱與祖先類中的某個方法名稱相同的情形)