【问题标题】:Delphi - Create instance of subclassDelphi - 创建子类的实例
【发布时间】:2010-08-22 14:43:39
【问题描述】:

我有一个类定义为:

TfraFrame = class(TFrame);

那么我有几个子类都继承自这个,例如:

TfraUsers = class(TfraFrame);
TfraGroups = class(TfraFrame);
TfraMenus = class(TfraFrame);

在我的主要形式中,我将变量声明为:

var
  fraUsers: TfraUsers;
  fraGroups: TfraGroups;
  fraMenus: TfraMenus;

现在我的问题是,我想要一个函数来控制每个类的实例的生成。每个类应该只有一个实例,但我只想在用户需要时创建实例。

我想这样传递变量:

procedure ShowFrame(Frame: TfraFrame)
begin
  if Frame = nil then
  begin
    Frame := TfraFrame.Create(self);
    Frame.Init(Panel1);
  end;

  Frame.Show;
end;

然后这样称呼它;

ShowFrame(fraUsers);

我期待它创建一个 TfraUsers 的实例(因为这是 fraUsers 被声明的内容),但是,我怀疑它可能正在创建一个 fraFrame 的实例。

有没有办法创建变量声明为的类型的实例?

【问题讨论】:

    标签: delphi oop


    【解决方案1】:

    是的,你需要告诉 showFrame 要实例化哪个类:

    添加

    type
      tfraFrameClass = class of TfraFrame;
    

    就在 tfraFrame 声明之后。并将 showFrame 更改为:

    function ShowFrame(Frame: TfraFrame; FrameClass: TfraFrameClass): TfraFrame;
    begin
      if Frame = nil then
      begin
        Result := FrameClass.Create(self);
        Result.Init(Panel1);
      end
      else
        Result := Frame;
    
      Result.Show;
    end;
    

    请注意,您不能将 Frame 作为 var 参数传递,因为编译器会坚持所传递参数的声明类型和实际类型完全相同。

    更新 更新示例以显示已分配的框架。

    更新 我忽略了在 OP 的代码中为 showFrame 过程分配 Create 调用的结果是行不通的。如果不声明为 var,则赋值不会超出 showFrame 过程的范围,传递给 showFrame 的变量的值不会改变。如上所述,将其声明为 var 也不起作用。解决方案是按照@Andreas 的建议做:使用无类型指针;或者像我一样让它成为一个功能。当然(笑)我更喜欢我的,因为这样可以更好地保持类型安全。

    当然,在我的示例中,目的是将 showFrame 函数的结果分配给适当的帧变量,如下所示:

    fraUsers := showFrame(fraUsers, TfraUsers);
    

    更新 或者,正如 Sertac 指出的那样,当您对传递给 showForm 的变量进行强制转换时,您仍然可以使用带有 var 参数的过程。

    procedure showFrame(var Frame: TfraFrame; FrameClasse: TfraFrameClass);
    begin
      if Frame = nil then
      begin
        Frame := FrameClass.Create(self);
        Frame.Init(Panel1);
      end;
    
      Frame.Show;
    end;
    

    并将其称为:

    showFrame(TfraFrame(fraUsers), TFraUsers);
    

    【讨论】:

    • 是的,那么是什么阻止他将函数的结果分配给var呢?他可能在他的原始代码中认为它可以通过将 Create 的结果分配给传入的参数来工作,但这不起作用,即使它被声明为 var 因为使用 var 参数 Delphi 会抱怨实际并且声明的类型不同。
    • "不能将 Frame 作为 var 参数传递" - 为什么不强制转换? ShowFrame(TfraFrame(fraUsers), TfraUsers),那么我们可以把它变成一个“程序”。
    • @Sertac:当然,是的,这也可以。没想到。编辑了我的答案以包含该选项。
    【解决方案2】:

    我建议你让你的框架变量属性

    property fraUsers: TfraUsers read GetfraUsers write ffraUsers;
    ..
    
    function GetFraUsers: TFraUsers;
    begin
      if fFraUsers = nil then
         fFraUsers := TfraUsers.Create(...);
      Result := ffraUsers;
    end;
    
    Then
    
    procedure ShowFrame(Frame: TfraFrame)
    begin
      Frame.Init(Panel1);
      Frame.Show;
    end;
    
    procedure form1.Button1Click(...)
    begin
      ShowFrame(fraUsers); // creates the frame if it does not exist
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 2011-11-02
      • 1970-01-01
      相关资源
      最近更新 更多