代码之家  ›  专栏  ›  技术社区  ›  SimaWB

检查类名

  •  4
  • SimaWB  · 技术社区  · 16 年前

    我不知道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 回复  |  直到 16 年前
        1
  •  12
  •   Community Mohan Dere    8 年前

    如果您无法访问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;
    

    其他班级也是如此。现在,您只需要决定是创建一次适配器并传递它,还是创建一个在任何需要的地方调用的函数,这将为您的具体类提供一个适配器。

    如果您使用接口实现适配器,那么您甚至不需要自己管理适配器的生命周期。

    这样你就可以得到乌尔里希给出的多态行为 his answer ,但无需更改TFirstClass和TSecondClass。

        2
  •  11
  •   Uli Gerhardt    16 年前

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

    乌利。

        3
  •  -1
  •   Germán Estévez -Neftalí-    16 年前

    起初,请原谅我英语不好。
    如果你不能在响应之前执行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

    当做。

    推荐文章