Q: BEST PRACTICES

Q: BEST PRACTICES

I have a question regarding best practices in defining a method as abstract in a parent/ancestor class, that is called from said parent/ancestor, but only implemented in descendant classes.

Below is an example that details my question further. Basically, I'm not sure if this method is considered "best practices" and I wondered if there was a more preferred method...

// ** 2014-09-11 10:30am GMT-8
// ** Reworked the code with the advice, moved the ancestor virtual/abstract method to "protected" and added "override" in the GetValue() method declared in the descendant. 
// ** As a result, it doesn't look like I need to "cast" or pass a "sender/self" variable. 
// ** I've never heard of "SOLID", I'll look into it.


unit TEST_classinheritance2_main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type

   TClass1 = class
   protected
      function GetValue() : integer; virtual; abstract;
   public
      procedure AMethod();
   end;

   TClass2 = class(TClass1)
   private
      function GetValue() : integer; override;
   public
   end;


{$REGION 'Form'}
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
{$ENDREGION}

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TClass1.AMethod();
begin

// * ABSTRACT ERROR
// *
// * The following line will ONLY generate an EAbstractError,
// * if the "override" keyword is not used in the declaration of the
// * method in the descendant class

   try
      // * ABSTRACT ERROR IN THIS LINE UNLESS "OVERRIDE" is USED
      showMessage(format('GetValue():[%d]', [self.GetValue()]));
   except
      on E:Exception do
         showMessage(E.Message);
   end;
end;

function TClass2.GetValue() : integer;
begin
   result := 2;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   AClass2 : TClass2;
begin

   AClass2 := TClass2.Create();
   try
      AClass2.AMethod();
   finally
     AClass2.Free();
   end;
end;

end.

Comments

  1. The compiler probably will give you a message about a lower visibility of the overridden method. So that also should be protected. And also congratulations, you just discovered the polymorphism achievement :)

    ReplyDelete
  2. Many thanks. Sure glad that I went through this exercise by making simplified code. It was ugly trying to figure this out with a big project. Thanks again guys.

    [DCC Hint] TEST_classinheritance2_main.pas(20): H2269 Overriding virtual method 'TClass2.GetValue' has lower visibility (private) than base class 'TClass1' (protected)

    Sure enough. Moved GetValue() to protected as well in the descendant. 

    +1 to Polymorphic Abilities

    ReplyDelete

Post a Comment