TButton := class of TControl

TButton = class(TControl)
有什么区别?分别在什么时候使用?请指教!

解决方案 »

  1.   

    TFormStatBasFltClass= class of TFormStatBasFlt;
      TFormStatBasFlt = class(TFormBas)
        Panel1: TPanel;
        Panel3: TPanel;
        btnOK: TButton;
        btnCancel: TButton;
        Button1: TButton;
    ........这样写有什么用,为什么要这样写呢?
      

  2.   

    class of TControl
    是一个“类之类”,class of class,相当于类的指针。可以这样用:
    type
      controlclass = class of tcontrolvar
      cc: controlclass;
    begin
      cc:=tbutton;
      with cc.create(nil) do
      ...  cc:=tlabel;
      with cc.create(nil) do
      ...
    end;这样你即使不知道要创建的是什么,也可以创建它。TButton = class(TControl)
    是类声明,
      

  3.   

    TFormStatBasFltClass= class of TFormStatBasFlt;
      TFormStatBasFlt = class(TFormBas)
        Panel1: TPanel;
        Panel3: TPanel;
        btnOK: TButton;
        btnCancel: TButton;
        Button1: TButton;
    ........这样写有什么用,为什么要这样写呢?
    ==================================================这样的好处是:
    假设你从TFormStatBasFlt继承出两个新的form类,分别为:TFlt1和TFlt2,有可能它们是放在dll中的,可以动态增加许多这样的类,这种情况下你无法确切的知道你要创建的对象究竟是TFlt1型的还是TFlt2型的,或者是TFlt3型的,因为在编译主程序时,你根本不知道有这两个类存在,但是你的dll可以导出这样的函数:
    function GetClass():TFormStatBasFltClass;
    那么通过调用dll中的这个函数,你就可以得到TFlt1或者TFlt2,在主程序中只要这样写:
    var
      fltclass:TFormStatBasFltClass;
      flt:TFormStatBasFlt;
    begin
      fltclass:=GetClassFromDll(SpecialDllHandle);
      flt:=fltclass.Create();
      ...
    end;
    就可以使用这个你在编写程序时并不认识的类了。不知道说清楚了没有
      

  4.   

    其实这样做的基本功能就是,可以对类的类型像变量一样进行赋值和传递,又可以像类型一样对具体的对象进行构造.具体的使用我现在也只想到使用在动态系统中:
    就是上面说的,可以将类实现封装在dll中,在运行时构建这个类,当然这个类必须从你预先定义的基类继承下来,在你的程序中都使用virtual方法来执行该类中的功能,(这样使用的话,需要用runtime bpl编译dll和主程序)另外,我现在在做的一个程序,需要将类对象保存到数据库中,我也使用了类似功能:
    在系统建立时先建立一个类与类名的对应表,在读入数据时,先得到要创建对象的类名,到全局的对应表中找到它的类型(就是将这个class of class通过作为返回值),然后用这个类型来具体创建我所需要的对象,程序就好像这样:
    type
      TObjectClass = Class of TObject;procedure xx();
    var
      oc:TObjectClass;
      ob:TObject;
    begin
      while (not recordset.eof) do begin
        oc:=G_ClassTable.GetClassFromName(recordset.FieldByName('classname'));
        if oc<>nil then begin
          ob:=oc.Create();
          ob.Initialize(recordset);
        end;
        recordset.movenext;
      end;
    end;==============
    同样的功能,如果使用原始的功能就可能变成:
    procedure xx();
    var
      classname:string;
      ob:TObject;
    begin
      while (not recordset.EOF) do begin
        classname:=recordset.FieldByName('classname');
        if (classname='TClassA') then
          ob:=TClassA.Create()
        else if (classname='TClassB') then
          ob:=TClassB.Create()
        else
          ...........
     
        recordset.MoveNext();
      end;
    end;
    当然这样也没有什么不可,只是程序在维护上可能会费一点力气.