基类的类过程应该实例化一个后代的对象?

时间:2009-08-05 15:33:20

标签: delphi

为什么在下面的代码中,我是否收到“失败”消息而不是“成功”消息

背景:我喜欢让类过程实例化它们的所有者对象,做某事,然后释放它。

但是,如果我有一个后代对象,这种方法不起作用:

有关如何在可被称为子级的基类中提供类过程的任何建议?我错误地想到了这个吗?

Type
  TBase = class(TObject)
    Protected
       Procedure Proc1; Virtual;
    Public
       Class Procedure MyClassProc;
  end;

  Class Procedure TBase.MyClassProc;
  Var
    Base: TBase;
  begin
    Base := TBase.Create;
    Base.Proc1;
    Base.Free;
  end;

  Procedure TBase.Proc1;
  begin
    Assert(FALSE, 'Failed');
  end;

type
   TChild = class(TBase)
   protected
      Procedure Proc1; Override;
   end;

   Procedure TChild.Proc1;
   begin
     ShowMessage('Succeeded');
   end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TChild.MyClassProc;
end;

3 个答案:

答案 0 :(得分:5)

您可以使用元编程轻松完成!只需将“TBase.Create”改为“Self.Create”,“self”代表当前的类,如果是子类的基础则不会满足。

Type
  TBase = class(TObject)
    Protected
       Procedure Proc1; Virtual;
    Public
       Class Procedure MyClassProc;
  end;

  Class Procedure TBase.MyClassProc;
  Var
    MyObject: TBase;
  begin
    // MyObject := TBase.Create;
    MyObject := Self.Create; // The Magic goes here, self is the class that's calling this method, in this case, TChild }
    MyObject.Proc1;
    MyObject.Free;
  end;

  Procedure TBase.Proc1;
  begin
    Assert(FALSE, 'Failed');
  end;

type
   TChild = class(TBase)
   protected
      Procedure Proc1; Override;
   end;

   Procedure TChild.Proc1;
   begin
     ShowMessage('Succeeded');
   end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TChild.MyClassProc;
end;

答案 1 :(得分:1)

将所有内容剥离到最低限度,您将看到您只创建了一个TBase实例,因此只会调用TBase.Proc1()。如果你想要调用TChild.Proc1(),你需要创建一个TChild实例,让多态实现其魔力。

然而,有可能有更好的方法来实现你的目标(不管它是什么),而不是让类方法创建一个对象实例来做某事。也许你应该澄清你的问题。

答案 2 :(得分:1)

这是

添加

TBase = class;
TBaseClass = class of TBase;

TBase = class(TObject)
protected
  class function GetBaseClass: TBaseClass; virtual;

function TBase.GetBaseClass: TBaseClass;
begin
  Result := TBase;
end;

TChild = class(TBase)
protected
  class function GetBaseClass: TBaseClass; override;

function TChild.GetBaseClass: TBaseClass;
begin
  Result := TChild;
end;

更改

来自

Base := TBase.Create;

Base := GetBaseClass.Create;

享受你的工作

啦啦队

Pham