為什么使用接口?
舉個例子好了:有這樣一個賣票服務(wù),電影院可以賣票,歌劇院可以賣票,客運站也可以賣票,那么我們是否需要把電影院、、歌劇院和客運站都設(shè)計成一個類架構(gòu)以提供賣票服務(wù)?要知道,連經(jīng)理人都可以賣票,很顯然不適合把經(jīng)理人也包括到賣票服務(wù)的繼承架構(gòu)中,我們需要的只是一個共通的賣票服務(wù)。于是,賣票的服務(wù)是個接口,電影院、歌劇院什么的只要都遵循這樣一個服務(wù)定義就能很好地相互交互和溝通(如果須要的話)。
如何在Delphi中使用接口?
1、聲明接口
IMyInterface = interface(IInterface) //說明(1)
[’{63E072DF-B81E-4734-B3CB-3C23C7FDA8EA}’] //說明(2)
function GetName(const str: String): String; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; //說明(3)
function _AddRef: Integer; stdcall; //使接口引用數(shù)加1。
function _Release: Integer; stdcall;//使接口引用數(shù)減1,當(dāng)小于等于0時作釋放動作。
end;
說明(1):如果有繼續(xù)關(guān)系則在括號里填父接口,否則省卻,如:IMyInterface = interface這樣就行。
說明(2):此GUID可選,如果要實現(xiàn)具有COM特性的接口的話則需要加上,Delphi中對于有GUID的接口在運行時在VMT表的預(yù)定位置生成接口的信息,如接口方法的定義、方法參數(shù)定義能詳細(xì)信息。
說明(3):接口必須實現(xiàn)這三個函數(shù)。
2、接口的實現(xiàn)
接口服務(wù)是由類來實現(xiàn)的。
TIntfClass = class(TObject, IMyInterface)
private
FCounter: Integer;
FRefCount: Integer;
public
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
...
end;
3、獲取接口
a. 使用類型轉(zhuǎn)換。 如:
var aIntf: IMyInterface;
begin
aObj := TIntfClass.Create;
try
aIntf := (IMyInterface(aObj);
...
b. 利用Delphi編譯器內(nèi)建機(jī)制。 如:aIntf := aObj。
c. 利用對象的QueryInterface方法。如OleCheck(aObj.QueryInterface(IID, aIntf)); 只能存取有GUID的COM接口。
d. 利用as操作符。
使用as操作符必須符合下面條件:
1.接口必須明確地指定是從IInterface接口繼承下來。
2.必須擁有GUID值。
在Delphi7中接口的實現(xiàn)類還必須是從TInterfacedObject繼承下來才行,如:
TIntfClass = class(TInterfacedObject, IMyInterface)
4、接口和對象生命期
因為Delphi會自行檢查接口如果在使用后沒有釋放而在生成的程序里加上釋放代碼,但也因這樣帶來了問題,如下面代碼:
var
i: Integer;
aObj: TIntfClass;
aIntf: IMyInterface;
begin
aObj := TIntfclass.Create;
try
aIntf := aObj;
aIntf.GetName...
finally
aIntf := nil;
FreeAndNil(aObj);
end;
北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |