继承类覆盖虚方法依赖项

时间:2013-11-13 10:39:08

标签: delphi delphi-7

我有这两个班级:

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我必须inherited TMyBaseClass.DoSomething,但我希望它尊重if not FAllowDoSomething then <don't do anything>

我尝试在Abort中使用TMyBaseClass,但我发现这不是一个好主意,会打破调用方法(TForm1.Button1Click);

如果不在if not FAllowDoSomething then Exit中再次编写TMyChildClass ,这样做的正确方法是什么。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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;