10

私はこれらの2つのクラスを持っています:

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>

で使用AbortしてみましたTMyBaseClassが、それは良い考えではなく、呼び出しメソッドを壊すことに気付きました ( TForm1.Button1Click);

if not FAllowDoSomething then Exit もう一度書くことなく、これを行う正しいアプローチは何ですかTMyChildClass

4

2 に答える 2

11

重要なポイントは、基本クラスでブール値のチェックを 1 回実行することです。したがって、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 に答える