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:
- Call
Freeon the object to release allocated memory; - Set the variable to
nilto 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; virtualmarks the base method as virtual to enable runtime polymorphism;- The subclass overrides
Crywith theoverridemodifier; - The variable is declared as
TAnimal, but holds an actualTDoginstance, 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
virtualbecome virtual; - You must use
overridewhen redefining an inherited virtual method in a subclass, otherwise the compiler emits a warning; - Use
reintroduceif 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