2009-02-09 19 views
4

我不知道OWNER對象類的名稱。所以我必須檢查我的代碼中的任何地方:檢查類名

if TObject(OWNER) is TFirstClass then begin 
    TFirstClass(OWNER).FirstFunction; 
    TFirstClass(OWNER).SecondFunction; 
    ... 
end else 
if TObject(OWNER) is TSecondClass then begin 
    TSecondClass(OWNER).FirstFunction; 
    TSecondClass(OWNER).SecondFunction; 
    ... 
end; 

有沒有更好的方法?因爲如果條件在代碼的許多地方我必須這樣做。 TFirstClass和TSecondClass(我必須運行)的所有功能都是相同的。

注:我使用Delphi 5.

+0

你是否控制了業主? (你能改變班級的定義嗎?) – 2009-02-09 16:29:26

+0

OWNER是什麼類型。當你對TObject進行類型轉換時,我假設指針或整數/紅衣主教? – 2009-02-09 21:21:57

回答

12

如果你有TFirstClass和TSecondClass用不上,但還是要簡化代碼,這裏有一個辦法:

創建一個適配器的基類:

type 
    TMyAdapter = class(TObject) 
    public 
    procedure FirstMethod; virtual; abstract; 
    procedure SecondMethod; virtual; abstract; 
    end; 

然後創建一個子類TFirstClassAdapter和TSecondClassAdapter並分別爲它們分別提供TFirstClass或TSecondClass的實例的私有引用。添加一個設置此引用的構造函數。覆蓋適配器類的方法,以便它們調用適配的類。

type 
    TFirstClassAdapter = class(TMyAdapter) 
    private 
    fObject: TFirstClass; 
    public 
    constructor Create(AAdaptedObject: TFirstClass); 

    procedure FirstMethod; override; 
    procedure SecondMethod; override; 
    end; 

constructor TFirstClassAdapter.Create(AAdaptedObject: TFirstClass); 
begin 
    inherited Create; 
    fObject := AAdaptedObject; 
end; 

procedure TFirstClassAdapter.FirstMethod; 
begin 
    fObject.FirstMethod; 
end; 

procedure TFirstClassAdapter.SecondMethod; 
begin 
    fObject.SecondMethod; 
end; 

與其他班級相同。現在你只需要決定是否創建一次適配器並傳遞它,或者你是否創建了一個你需要的地方調用的函數,以及哪個函數會爲你的具體類提供一個適配器。

如果您使用接口實現適配器,那麼您甚至不需要自己管理適配器的生存期。

通過這種方式,您可以獲得Ulrich在his answer中給出的多態行爲,但無需更改TFirstClass和TSecondClass。

11

派生TFirstClass和TSecondClass從聲明虛擬方法了firstFunction和SecondFunction一個共同的基類。

Uli。

-1

起初我對我英語不好。
如果在響應(適配器和派生自基類)之前不能執行2,則可以使用RTTI按名稱訪問過程。

該過程必須在已發佈部分中聲明。

如果你已經像這樣的聲明:

TFirstClass = class(TObject) 
    published 
    procedure FirstFunction; 
    procedure SecondFunction; 
    end; 
    TSecondClass = class(TObject) 
    published 
    procedure FirstFunction; 
    procedure SecondFunction; 
    end 

你可以做這樣的事情,如果你有名稱來執行方法:

// Acceso a la rutina; TObject is a Base class for 
    // TFirstClass and TSecondClass 
    Routine.Data := Pointer(obj as TObject); 
    // Devuelve la dirección de un método published; Method for it's name 
    Routine.Code := (obj as TObject).MethodAddress('SecondFunction'); 
    // Not find 
    if (Routine.Code = nil) then Exit; 
    // execute 
    TExecuteMethod(Routine); 

你可以在這裏看到類似的代碼:
* Tip4 * Tip7

問候。