Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inherited class override virtual method dependency

I have these 2 classes:

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;

In TMyChildClass.DoSomething I must inherited the TMyBaseClass.DoSomething but I want it to respect the if not FAllowDoSomething then <don't do anything>.

I have tried using Abort in the TMyBaseClass but I realize it's not a good idea and will break the calling method (TForm1.Button1Click);

What is the correct approach of doing this, without writing the if not FAllowDoSomething then Exit again in TMyChildClass.

like image 812
ZigiZ Avatar asked Nov 13 '13 10:11

ZigiZ


1 Answers

The key point is to perform the check on the boolean once, in the base class. So, make DoSomething non-virtual and implement it in your base class like this:

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

where DoSomethingImplementation is a virtual method that you override in your derived classes.

The base class then looks like this:

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

Your derived class looks like this:

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

Your overridden method looks like this:

procedure TMyDerivedClass.DoSomethingImplementation;
begin
  inherited;
  ShowMessage(...);
end;
like image 133
David Heffernan Avatar answered Sep 19 '22 20:09

David Heffernan