Inheritance and Virtual Methods

Inheritance, Virtual Methods, override, reintroduce

Example of Class Inheritance

Object Pascal supports inheritance and virtual methods. In the example below, TDog inherits from TAnimal:

TDog is the derived class (subclass), while TAnimal is the base class (parent class)

program AnimalDemo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$codepage utf8}
uses SysUtils;

type
  // Base class for animals
  TAnimal = class
    procedure Cry; virtual; // Virtual method: animal makes sound
  end; // End of class definition, only end; required

  // Dog subclass, inherits Animal and overrides cry sound
  TDog = class(TAnimal)
    procedure Cry; override;
  end;

procedure TAnimal.Cry;
begin
  WriteLn('Animal makes a sound');
end;

procedure TDog.Cry;
begin
  WriteLn('Woof woof woof');
end;

var
  Pet: TAnimal;
begin
  // Base class instance
  Pet := TAnimal.Create;
  try
    Pet.Cry;
  finally
    FreeAndNil(Pet);
  end;

  // Subclass instance assigned to base class variable, polymorphism takes effect
  Pet := TDog.Create;
  try
    Pet.Cry;
  finally
    FreeAndNil(Pet);
  end;
end.Code language: JavaScript (javascript)

Execution Output

D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
Linking mydemo.exe
45 lines compiled, 0.1 sec, 68544 bytes code, 4260 bytes data

D:\fpcdemo>mydemo
Animal makes a sound
Woof woof woofCode language: CSS (css)

FreeAndNil

Safely release objects, combines two operations into one:

  1. Call Free on the object to release allocated memory;
  2. Set the variable to nil to prevent dangling pointers.

The code above stores a TDog subclass object inside a TAnimal-type variable named Pet. When invoking Cry via Pet afterward, it executes the Cry method defined in TDog instead of the one in TAnimal — this is polymorphism.

  • Cry; virtual marks the base method as virtual to enable runtime polymorphism;
  • The subclass overrides Cry with the override modifier;
  • The variable is declared as TAnimal, but holds an actual TDog instance, automatically triggering the dog’s cry implementation.

For methods marked virtual: The compiler resolves the matching method implementation at runtime based on the object’s actual type.

If you remove virtual and override

Both calls will execute the base class method

The above screenshot shows the result after deleting virtual and override

All output comes from the TAnimal implementation

The compiler only recognizes the declared variable type TMyClass and ignores the object’s real runtime type.

  • Ordinary methods are non-virtual by default; only methods labeled virtual become virtual;
  • You must use override when redefining an inherited virtual method in a subclass, otherwise the compiler emits a warning;
  • Use reintroduce if you want to hide the parent class’s virtual method of the same name without overriding it (not recommended as it causes confusion), equivalent to the new keyword in C#

Inheritance and Virtual Methods

Leave a Reply

Your email address will not be published. Required fields are marked *