检查班级名称

时间:2009-02-09 16:25:12

标签: delphi class

我不知道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。

3 个答案:

答案 0 :(得分: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。

答案 1 :(得分:11)

从声明虚方法FirstFunction和SecondFunction的公共基类派生TFirstClass和TSecondClass。

乌利。

答案 2 :(得分:-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

问候。