10

我有这两个类:

type
  TMyBaseClass = class
  protected
    FAllowDoSomething: Boolean; // initialized to False
    procedure DoSomething; virtual;
  end;

  TMyChildClass = class(TMyBaseClass)
  protected
    procedure DoSomething; override;
  end;

implementation

procedure TMyBaseClass.DoSomething;
begin
  if not FAllowDoSomething then Exit; // Abort;
  ShowMessage('TMyBaseClass: FAllowDoSomething is False. You wont see me!');
end;

procedure TMyChildClass.DoSomething;
begin
  inherited; // Must inherit
  // if not FAllowDoSomething then Exit; { I don't want to check here again }
  ShowMessage('TMyChildClass: FAllowDoSomething is False but still I can see this message!');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TMyBaseClass.Create do try
    DoSomething;
  finally
    Free;
  end;    

  // if I use Abort in TMyBaseClass, the code will not get here

  with TMyChildClass.Create do try
    DoSomething;
  finally
    Free;
  end;
end;

TMyChildClass.DoSomething我必须inheritedTMyBaseClass.DoSomething但我希望它尊重if not FAllowDoSomething then <don't do anything>

我曾尝试使用Abortin ,TMyBaseClass但我意识到这不是一个好主意,并且会破坏调用方法 ( TForm1.Button1Click);

这样做的正确方法是什么,而不用if not FAllowDoSomething then Exit .TMyChildClass

4

2 回答 2

11

关键是在基类中对布尔值执行一次检查。因此,将 DoSomething 设为非虚拟并在您的基类中实现它,如下所示:

procedure TMyBaseClass.DoSomething;
begin
  if FAllowDoSomething then
    DoSomethingImplementation;
end;

其中 DoSomethingImplementation 是您在派生类中重写的虚拟方法。

基类如下所示:

type
  TMyBaseClass = class
  private
    FAllowDoSomething: Boolean;
  protected
    procedure DoSomethingImplementation; virtual;
  public
    procedure DoSomething;
  end;

您的派生类如下所示:

type
  TMyDerivedClass = class(TMyBaseClass)
  protected
    procedure DoSomethingImplementation; override;
  end;

您的覆盖方法如下所示:

procedure TMyDerivedClass.DoSomethingImplementation;
begin
  inherited;
  ShowMessage(...);
end;
于 2013-11-13T10:49:07.820 回答
0

您需要捕获Abort异常。

procedure TMyBaseClass.DoSomething;
begin
  if not FAllowDoSomething then Abort;
  ShowMessage('TMyBaseClass: FAllowDoSomething is False. You wont see me!');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TMyBaseClass.Create do
  try
    try
      DoSomething;
    finally
      Free;
    end;    
  except
    on EAbort do ;
  end;

  // the code will get here

  with TMyChildClass.Create do
  try
    try
      DoSomething;
    finally
      Free;
    end;    
  except
    on EAbort do ;
  end;
end;
于 2013-11-13T10:55:16.417 回答